遇到問題--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分別是三組情況。