遇到问题--mongodb---多个criteria.orOperator或者多个criteria.andOperator报错
报错
在使用java驱动构造mongodb查询过程中发现多个criteria.orOperator或者多个criteria.andOperator报错。
报错信息如下:
you can't add a second '$or' expression specified $or
解决方法
andOperator
假设我们有四个查询条件,criteria是主查询criteria。
Criteria criteria= new Criteria();
Criteria criteriaA= new Criteria();
Criteria criteriaB= new Criteria();
Criteria criteriaC= new Criteria();
Criteria criteriaD= new Criteria();
错误方式
criteria.andOperator(criteriaA,criteriaB);
criteria.andOperator(criteriaC,criteriaD);
正确方式
criteria.andOperator(criteriaA,criteriaB,criteriaC,criteriaD);
orOperator
错误的方式
criteria.orOperator(criteriaA,criteriaB);
criteria.orOperator(criteriaC,criteriaD);
正确的方式
orOperator的情况比较复杂。
情况一
如果是针对同样的字段进行or。则可以使用:
criteria.orOperator(criteriaA,criteriaB,criteriaC,criteriaD);
例如:
-
Criteria c1= Criteria.where("year").gte(startYear).lte(endYear).and("month").is(endMonth).and("day").gte(startDay).lte(endDay)
-
.and("hour").gte(startHour).lte(endHour).and("minute").is(startMinute).and("second").gte(startSecond);
-
Criteria c2=Criteria.where("year").gte(startYear).lte(endYear).and("month").is(endMonth).and("day").gte(startDay).lte(endDay)
-
.and("hour").gte(startHour).lte(endHour).and("minute").is(endMinute).and("second").lte(endSecond);
-
Criteria c3 =Criteria.where("year").gte(startYear).lte(endYear).and("month").is(endMonth).and("day").gte(startDay).lte(endDay)
-
.and("hour").gte(startHour).lte(endHour).and("minute").gt(startMinute).lt(endMinute);
-
Criteria cr = new Criteria();
-
query = new Query(cr.orOperator(c1,c2,c3));
-
getMongoTemplate().find(query, SensorCollection.class);
情况二
如果针对的是不同的字段,几个字段之间是or 但是 分成几组情况,每组必须满足其中一个条件。
这种情况需要使用andOperator把多个orOperator连接起来。每个orOperator是一组情况。
如下:
-
Criteria criteria = new Criteria();
-
MapSafeGetter param = new MapSafeGetter(req.getSearch());
-
Criteria criteriaSearch = new Criteria();
-
if (!StringUtils.isEmpty(param.getString("searchValue"))) {
-
criteriaSearch.orOperator(Criteria.where("orderId").is(param.getString("searchValue")),
-
Criteria.where("productName").regex(".*?" + param.getString("searchValue") + ".*"),
-
Criteria.where("coupon").regex(".*?" + param.getString("searchValue") + ".*"),
-
Criteria.where("receiver").regex(".*?" + param.getString("searchValue") + ".*"),
-
Criteria.where("mobile").is(param.getString("searchValue")),
-
Criteria.where("reason").regex(".*?" + param.getString("searchValue") + ".*"));
-
}
-
if (!StringUtils.isEmpty(param.getString("productId"))) {
-
criteria.and("productId").is(param.getString("productId"));
-
}
-
criteria.and("dealed").is(false);
-
criteria.and("invalid").ne(true);
-
Criteria criteriaOk = new Criteria();
-
criteriaOk.orOperator(
-
Criteria.where("backReceived").ne(true),
-
Criteria.where("approved").ne(true)
-
);
-
Criteria criteriaTime = new Criteria();
-
if (!StringUtils.isEmpty(param.getString("beginTime")) || !StringUtils.isEmpty(param.getString("endTime"))) {
-
Criteria criteriaApplyTime = new Criteria();
-
criteriaApplyTime = criteriaApplyTime.and("applyTime");
-
Criteria criteriaDealTime = new Criteria();
-
criteriaDealTime = criteriaDealTime.and("dealTime");
-
if (!StringUtils.isEmpty(param.getString("beginTime"))) {
-
criteriaApplyTime.gte(DateUtils.parse(param.getString("beginTime")));
-
criteriaDealTime.gte(DateUtils.parse(param.getString("beginTime")));
-
}
-
if (!StringUtils.isEmpty(param.getString("endTime"))) {
-
criteriaApplyTime.lte(DateUtils.parse(param.getString("endTime")));
-
criteriaDealTime.lte(DateUtils.parse(param.getString("endTime")));
-
}
-
criteriaTime.orOperator(criteriaApplyTime, criteriaDealTime);
-
}
-
criteria.andOperator(criteriaTime,criteriaSearch,criteriaOk);
-
Query query = Query.query(criteria);
-
query.with(new Sort(Sort.Direction.DESC, "applyTime"));
-
long count = mongoTemplate.count(query, Cashback.class);
criteriaTime,criteriaSearch,criteriaOk分别是三组情况。