【问题标题】:How can i add or & and Criteria clauses with in a single Query Object Mongodb Spring data如何在单个查询对象 Mongodb Spring 数据中添加 or & 和 Criteria 子句
【发布时间】:2014-10-15 01:00:51
【问题描述】:

我想同时向我的查询对象添加 or & 和子句,但我不断收到错误提示

由于 com.mongodb.BasicDBObject 的限制,不能添加第二个 'null' 条件?

例如

query.addCriteria(new Criteria().orOperator(Some Critera);


 query.addCriteria(new Criteria().andOperator(Some Critera);

谁能帮我解决这个问题?

详情:

实际上我正在尝试解析以下 json 并基于该解析的 json 构建动态查询

{
  "query":{

    "where":[{

              "or":[
              {
                 "fieldName":"address1","fieldValue":"Dummy address1",

                 "operator":"equal"
              }

            ],
            "and":[{
                  "fieldName":"version","fieldValue":"1",

                 "operator":"equal"

             }]
           }
        ]
   }
}

因此,您可以建议我使用 mongoTemplate spring data 将该 json 解析为 Mongodb 查询的其他方法

这是我的解析代码

if(null != eventSearch.getQuery())
        {

            if(null != eventSearch.getQuery().getWhere() && eventSearch.getQuery().getWhere().size() > 0)
            {

                for (Where whereClause : eventSearch.getQuery().getWhere()) {

                      if(null != whereClause.getOr() && whereClause.getOr().size() > 0){

                          List<org.springframework.data.mongodb.core.query.Criteria> orCriterias = new ArrayList<org.springframework.data.mongodb.core.query.Criteria>(whereClause.getOr().size());

                          for (Field field: whereClause.getOr()) {

                              if(field.getOperator().equalsIgnoreCase(QueryOperator.IS))
                              {
                                orCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).is(field.getFieldValue()));

                              }else if(field.getOperator().equalsIgnoreCase(QueryOperator.LT)){

                                orCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).lt(field.getFieldValue()));
                              } 
                              else if(field.getOperator().equalsIgnoreCase(QueryOperator.GT)){

                                  orCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).gt(field.getFieldValue()));
                              } 
                              else if(field.getOperator().equalsIgnoreCase(QueryOperator.LTE)){

                                  orCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).lte(field.getFieldValue()));
                               }
                              else if(field.getOperator().equalsIgnoreCase(QueryOperator.GTE)){

                                  orCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).gte(field.getFieldValue()));
                               }
                          } 

                          query.addCriteria(new org.springframework.data.mongodb.core.query.Criteria().orOperator(orCriterias.toArray(new org.springframework.data.mongodb.core.query.Criteria[whereClause.getOr().size()])));
                      }

                      if(null != whereClause.getAnd() && whereClause.getAnd().size() > 0){

                          List<org.springframework.data.mongodb.core.query.Criteria> andCriterias = new ArrayList<org.springframework.data.mongodb.core.query.Criteria>(whereClause.getAnd().size());

                          for (Field field: whereClause.getAnd()) {

                              if(field.getOperator().equalsIgnoreCase(QueryOperator.IS))
                              {
                                  andCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).is(field.getFieldValue()));

                              }else if(field.getOperator().equalsIgnoreCase(QueryOperator.LT)){

                                  andCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).lt(field.getFieldValue()));
                              } 
                              else if(field.getOperator().equalsIgnoreCase(QueryOperator.GT)){

                                  andCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).gt(field.getFieldValue()));
                              } 
                              else if(field.getOperator().equalsIgnoreCase(QueryOperator.LTE)){

                                  andCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).lte(field.getFieldValue()));
                               }
                              else if(field.getOperator().equalsIgnoreCase(QueryOperator.GTE)){

                                  andCriterias.add(org.springframework.data.mongodb.core.query.Criteria.where(field.getFieldName()).gte(field.getFieldValue()));
                               }
                          } 
                          //Getting exception at this line
                          query.addCriteria(new org.springframework.data.mongodb.core.query.Criteria().andOperator(andCriterias.toArray(new org.springframework.data.mongodb.core.query.Criteria[whereClause.getAnd().size()])));
                      }
}}

【问题讨论】:

    标签: java spring mongodb spring-data-mongodb


    【解决方案1】:

    你的代码太罗嗦了,我暂时把org.springframework.data.mongodb.core.query.Criteria换成了Criteria

        // added
        Query query = new Query();
    
        if(null != eventSearch.getQuery())
        {
    
            if(null != eventSearch.getQuery().getWhere() && eventSearch.getQuery().getWhere().size() > 0)
            {
                // added
                List<Criteria> wheres = new ArrayList<>();
    
                for (Where whereClause : eventSearch.getQuery().getWhere()) {
    
                    // added
                    Criteria where = new Criteria();
    
                      if(null != whereClause.getOr() && whereClause.getOr().size() > 0){
    
                          List<Criteria> orCriterias = new ArrayList<Criteria>(whereClause.getOr().size());
    
                          for (Field field: whereClause.getOr()) {
    
                              if(field.getOperator().equalsIgnoreCase(QueryOperator.IS))
                              {
                                orCriterias.add(Criteria.where(field.getFieldName()).is(field.getFieldValue()));
    
                              }else if(field.getOperator().equalsIgnoreCase(QueryOperator.LT)){
    
                                orCriterias.add(Criteria.where(field.getFieldName()).lt(field.getFieldValue()));
                              } 
                              else if(field.getOperator().equalsIgnoreCase(QueryOperator.GT)){
    
                                  orCriterias.add(Criteria.where(field.getFieldName()).gt(field.getFieldValue()));
                              } 
                              else if(field.getOperator().equalsIgnoreCase(QueryOperator.LTE)){
    
                                  orCriterias.add(Criteria.where(field.getFieldName()).lte(field.getFieldValue()));
                               }
                              else if(field.getOperator().equalsIgnoreCase(QueryOperator.GTE)){
    
                                  orCriterias.add(Criteria.where(field.getFieldName()).gte(field.getFieldValue()));
                               }
                          } 
    
                          // comment out
                          // query.addCriteria(new Criteria().orOperator(orCriterias.toArray(new Criteria[whereClause.getOr().size()])));
    
                          // replaced with
                          if (orCriterias.size() > 0) {
                              where.orOperator(orCriterias.toArray(new Criteria[0]));
                          }
                      }
    
                      if(null != whereClause.getAnd() && whereClause.getAnd().size() > 0){
    
                          List<Criteria> andCriterias = new ArrayList<Criteria>(whereClause.getAnd().size());
    
                          for (Field field: whereClause.getAnd()) {
    
                              if(field.getOperator().equalsIgnoreCase(QueryOperator.IS))
                              {
                                  andCriterias.add(Criteria.where(field.getFieldName()).is(field.getFieldValue()));
    
                              }else if(field.getOperator().equalsIgnoreCase(QueryOperator.LT)){
    
                                  andCriterias.add(Criteria.where(field.getFieldName()).lt(field.getFieldValue()));
                              } 
                              else if(field.getOperator().equalsIgnoreCase(QueryOperator.GT)){
    
                                  andCriterias.add(Criteria.where(field.getFieldName()).gt(field.getFieldValue()));
                              } 
                              else if(field.getOperator().equalsIgnoreCase(QueryOperator.LTE)){
    
                                  andCriterias.add(Criteria.where(field.getFieldName()).lte(field.getFieldValue()));
                               }
                              else if(field.getOperator().equalsIgnoreCase(QueryOperator.GTE)){
    
                                  andCriterias.add(Criteria.where(field.getFieldName()).gte(field.getFieldValue()));
                               }
                          } 
    
                          // comment out
                          // //Getting exception at this line
                          // query.addCriteria(new Criteria().andOperator(andCriterias.toArray(new Criteria[whereClause.getAnd().size()])));
    
                          // replaced with
                          if (andCriterias.size() > 0) {
                              where.andOperator(andCriterias.toArray(new Criteria[0]));
                          }
    
                      }
    
                      // added
                      wheres.add(where);
                    }
                    // added
                    if (wheres.size() > 0) {
                        query.addCriteria(new Criteria().andOperator(wheres.toArray(new Criteria[0])));
                    }
                }
        }
    

    如果您的操作符只包含 == != &lt; &lt;= &gt; &gt;=,您可以尝试通过直接或间接更改 JSON 来缩短代码,如下所示:

    {
      "query":{
    
        "where":[{
    
                  "or":[
                  {
                     "fieldName":"address1","fieldValue":"Dummy address1",
    
                     "operator":"equal"
                  },
                  {
                     "fieldName":"address1","fieldValue":"Dummy address2",
    
                     "operator":"$gt" // added: greater than
                  },
                  {
                     "fieldName":"address1","fieldValue":"Dummy address3",
    
                     "operator":"$ne" // added: not equal
                  }
    
                ],
                "and":[{
                      "fieldName":"version","fieldValue":"1",
    
                     "operator":"equal"
    
                 }]
               }
            ]
       }
    }
    

    那么,部分代码可以这样写:

      for (Field field: whereClause.getAnd()) {
    
          if(field.getOperator().equalsIgnoreCase(QueryOperator.IS))
          {
              andCriterias.add(Criteria.where(field.getFieldName()).is(field.getFieldValue()));
    
          } else {
              andCriterias.add(Criteria.where(field.getOperator()).is(new BasicDBObject(field.getFieldName(), field.getFieldValue())));
          }
      }
    

    whereClause.getOr()whereClause.getAnd() 类似,如果需要,可以将它们组合成一个循环以缩短代码。

    【讨论】:

    • @Ramzan Zafar,很高兴能帮到你。我添加了一些东西,也许它可以帮助优化代码。
    【解决方案2】:

    我无法真正帮助您解析代码,但您可以使用从内部级别构建查询

    DBObject conditions = new BasicDBObject("field1",val1).append("field2",val2)...;
    

    然后将它们链接在一起

    DBObject query = new BasicDBObject("$or",conditions);
    

    DBObject query = new BasicDBObject("$and",conditions);
    

    【讨论】:

    • 感谢您的效果!请查看我更新的问题!
    猜你喜欢
    • 2019-07-27
    • 1970-01-01
    • 2016-08-13
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 2022-07-14
    相关资源
    最近更新 更多