在 spring mongo 中使用条件运算符 [英] Using conditional operator in a spring mongo

查看:32
本文介绍了在 spring mongo 中使用条件运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关注我的 Mongo 查询

Following in my Mongo query

{$project:{
       id:"$_id",
       login:"$login",
       firstName: "$firstName",
       lastName:"$lastName",
       email:"$email",
       deactivateFlag:"$deactivateFlag",
       lastActivity:"$lastActivity",
       company :"$organization.name",
       RoleName :"$organization.roles.roleName",
       isMatchingRoles: { $eq: [ "$organization.roles.orgRoleId","$userOrgMap.roleId" ] }
      }
    },
    { $match: {isMatchingRoles:true},

这很好用.特别是最后一个 $match 可以完美地减少重复.但是当我尝试将上面的代码转换为 Spring 数据等效时,我面临以下问题.

This works perfectly fine. Particularly the last $match works perfectly to reduce the duplicates. But when I tried to convert the above code to Spring data equivalent, I am facing the following problem.

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:653) at java.util.ArrayList.get(ArrayList.java:429) at java.util.Collections$UnmodifiableList.get(Collections.java:‌​1309)

以下是我的 Spring Data 代码.我打印了原始输出,碰巧得到 isMatchingRoles 的布尔值,它是我的 bean 类的一部分,在聚合期间被映射.但是当使用 getMappedResult 映射布尔值时,我遇到了这个问题.

Following is my Spring Data code. I printed the raw output and happen to get boolean value for isMatchingRoles which is part of my bean class which is mapped during aggregation. But when the Boolean values is getting mapped using getMappedResult , I am getting this issue.

aggregation = newAggregation(
                        match(getUsersCriteria(searchTxt)), 
                        unwind("userOrgMap"),
                        lookup("organizations", "userOrgMap.orgId", "_id", "organization"),
                        unwind("organization"),
                        unwind("organization.roles"),
    project("userId", "login", "firstName", "lastName", "email", "deactivateFlag", "lastActivity")
                                .and("organization.name").as("companyName")
                                .and("organization.roles.roleName").as("roleName")
                                .and(when(where("organization.roles.orgRoleId").is("userOrgMap.roleId")).then(true).otherwise(false)).as("isMatchingRoles"),
                            match(Criteria.where("isMatchingRoles").is(true))

    AggregationResults<UserDTO> groupResults groupResults = mongoOperation.aggregate(aggregation, UserDTO.class, UserDTO.class);
                    System.out.println(" Raw result "+groupResults.getMappedResults().get(0));
                    // The above result is getting data properly for isMatchingRoles

                    List<UserDTO> result = groupResults.getMappedResults();
                      // I am getting the exception in the above code

                    System.out.println(" actual mapped Reesult "+result.size());

以下是我的输入类

@Document(collection = "users")
public class UserDTO {



    @Id
    private String userId;
    private String login;
    private String firstName;
    private String lastName;
    private String lastActivity;
    private String email;
    private boolean deactivateFlag;
    private String companyName;
    private String roleName;
    private boolean isMatchingRoles;



    public UserDTO(String userId, String login, String firstName, String lastName, String lastActivity, String email,
            boolean deactivateFlag, String companyName, String roleName, boolean isMatchingRoles) {
        super();
        this.userId = userId;
        this.login = login;
        this.firstName = firstName;
        this.lastName = lastName;
        this.lastActivity = lastActivity;
        this.email = email;
        this.deactivateFlag = deactivateFlag;
        this.companyName = companyName;
        this.roleName = roleName;
        this.isMatchingRoles = isMatchingRoles;
    }


    public String getUserId() {
        return userId;
    }


    public void setUserId(String userId) {
        this.userId = userId;
    }


    public String getLogin() {
        return login;
    }


    public void setLogin(String login) {
        this.login = login;
    }


    public String getFirstName() {
        return firstName;
    }


    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }


    public String getLastName() {
        return lastName;
    }


    public void setLastName(String lastName) {
        this.lastName = lastName;
    }


    public String getLastActivity() {
        return lastActivity;
    }


    public void setLastActivity(String lastActivity) {
        this.lastActivity = lastActivity;
    }


    public String getEmail() {
        return email;
    }


    public void setEmail(String email) {
        this.email = email;
    }


    public boolean isDeactivateFlag() {
        return deactivateFlag;
    }


    public void setDeactivateFlag(boolean deactivateFlag) {
        this.deactivateFlag = deactivateFlag;
    }


    public String getCompanyName() {
        return companyName;
    }


    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }


    public String getRoleName() {
        return roleName;
    }


    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }


    public boolean isMatchingRoles() {
        return isMatchingRoles;
    }


    public void setMatchingRoles(boolean isMatchingRoles) {
        this.isMatchingRoles = isMatchingRoles;
    }



}

以下是我的样本集

user collection


{
    "_id" : "123",
    "login" : "abc@abc.com",
    "firstName" : "xxx",
    "lastName" : "yyy",
    "email" : "abc@abc.com",
    "deactivateFlag" : false,
    "userOrgMap" : [
        {
            "orgId" : "999",
            "roleId" : "888"
        }
    ]
}


Organization collection


{
    "_id" : "999",
    "name" : "orgName",
    "roles" : [
        {
            "orgRoleId" : "888",
            "roleName" : "Standard User"
        },
        {
            "orgRoleId" : "777",
            "roleName" : "Company Administrator"
        }
    ]
}

推荐答案

您正在使用 (CriteriaDefinition) api(不确定为什么会在投影中公开,可能是因为聚合运算符确实共享了一些其函数与查询运算符 ) 生成条件表达式,该条件表达式应用于正则查询表达式(用于 $match 阶段和正则查找查询).

You are using the (CriteriaDefinition) api (not sure why is this exposed in projection, may be because aggregation operators does share some of its functions with query operators ) to generate the conditional expression, which should be used for regular query expressions( used in $match stage and regular find queries).

条件定义 api 生成以下查询.

The criteria definition api generates the following query.

"isMatchingRoles": {
    "$cond": {
        "if": {
            "$eq": ["$organization.roles.orgRoleId", "userOrgMap.roleId"]
        },
        "then": true,
        "else": false
    }
} 

注意 $eq 的第二个参数是字符串值而不是字段引用.

Notice the second argument to the $eq is string value rather than field reference.

您可以通过以下两种方式进行操作.

You can do it in following two ways.

使用 ConditonalOperator api.

.and(when(ComparisonOperators.Eq.valueOf("organization.roles.orgRoleId").equalTo("userOrgMap.roleId")).then(true).otherwise(false)).as("isMatchingRoles")

使用 AggregationExpression 生成条件表达式.

Use AggregationExpression to generate the conditional expression.

and(new AggregationExpression() {
            @Override
            public DBObject toDbObject(AggregationOperationContext context) {
                return new BasicDBObject("$cond",
                        Arrays.<Object>asList(
                                new BasicDBObject("$eq", 
                                        Arrays.asList("$organization.roles.orgRoleId", "$userOrgMap.roleId")),
                                true,
                                false));
            }
 }).as("isMatchingRoles");

这篇关于在 spring mongo 中使用条件运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆