Как я могу добавить предложения or & и Criteria с данными одного объекта запроса Mongodb Spring

Я хочу добавить предложения или & и к моему объекту запроса одновременно, но я продолжаю получать сообщение об ошибке ниже

Из-за ограничений com.mongodb.BasicDBObject вы не можете добавить второй «нулевой» критерий?

Например

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"

             }]
           }
        ]
   }
}

Итак, вы можете предложить мне другие способы разобрать этот json в запрос Mongodb, используя весенние данные mongoTemplate.

вот мой код разбора

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()])));
                      }
}}

person Ramzan Zafar    schedule 21.08.2014    source источник


Ответы (2)


Ваш код слишком логичен, я временно заменил 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(), тогда вы можете объединить их в цикл, чтобы сократить коды, если хотите.

person Wizard    schedule 21.08.2014
comment
@ Рамзан Зафар, приятно, что помог тебе. Я добавил кое-что, возможно, это поможет оптимизировать коды. - person Wizard; 22.08.2014

Я не могу помочь вам с кодом синтаксического анализа, но вы можете построить запрос с внутреннего уровня, используя

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

а затем связать их вместе с

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

а также

DBObject query = new BasicDBObject("$and",conditions);
person Trudbert    schedule 21.08.2014
comment
Спасибо за эффект! Пожалуйста, смотрите мой обновленный вопрос! - person Ramzan Zafar; 21.08.2014