如何添加或& amp;和Criteria子句在一个查询对象Mongodb Spring数据中

时间:2014-08-21 11:47:23

标签: java spring mongodb spring-data-mongodb

我想添加或者&并且同时对我的查询对象进行了子句但是我一直得到以下错误

由于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数据将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()])));
                      }
}}

2 个答案:

答案 0 :(得分:4)

您的代码过于苛刻,我暂时将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])));
                }
            }
    }

如果您的运营商仅包含 == != < <= > >=,您可以尝试通过直接或间接更改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()类似,如果您愿意,可以将它们组合在一个循环中以缩短代码。

答案 1 :(得分:1)

我无法真正帮助您解析代码,但您可以使用

从内层构建查询
DBObject conditions = new BasicDBObject("field1",val1).append("field2",val2)...;

然后将它们与

链接在一起
DBObject query = new BasicDBObject("$or",conditions);

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