Spring Boot Criteria API构建MongoDB $or+$and查询报错求助
解决Spring Boot Criteria API构建MongoDB嵌套查询的错误
问题描述
使用Spring Boot的Criteria API构建MongoDB查询时,遇到错误:
"Due to limitations of the org.bson.document, you can't add a second '$and' expression specified"
当前代码循环将单个条件添加到列表后使用orOperator,无法生成预期的多个$and条件嵌套在$or中的查询结构,预期的MongoDB查询结构如下:
db.price.find( { "$or" : [ {"$and" :[{ "item_id" : "1234"}, { "store_id" : "1447"}, { "code" : "XYZ"}]}, {"$and" :[{ "item_id" : "1234"}, { "store_id" : "1951"}, { "code" : "XYZ"}]}, {"$and" :[{ "item_id" : "1234"}, { "store_id" : "0536"}, { "code" : "XYZ"}]}, {"$and" : [{ "item_id" : "1234"}, { "store_id" : "1751"}, { "code" : "XYZ"}]} ] });
错误原因
当前代码的问题在于:循环中把每个ItemDto对应的三个独立条件直接加入同一个列表,最终orOperator会将所有条件平铺为$or的子条件,而非将每个ItemDto的三个条件先通过$and组合,再将这些组合结果放入$or中。这种平铺方式会导致MongoDB内部尝试自动合并条件时触发org.bson.document的限制,抛出错误。
修正代码
将每个ItemDto对应的三个条件先通过andOperator组合成单个Criteria,再将这些组合后的Criteria加入列表,最后用orOperator包裹:
Query query = new Query(); List<Criteria> criteriaList = new ArrayList<>(); for (ItemDto itemDto : itemDtoList) { // 对每个ItemDto,先组合三个条件为一个and查询 Criteria itemCriteria = new Criteria().andOperator( Criteria.where("item_id").is(itemDto.getClientId()), Criteria.where("store_id").is(itemDto.getItem().getStoreId()), Criteria.where("code").is(itemDto.getItem().getCode()) ); criteriaList.add(itemCriteria); } // 将所有and组合后的条件用or包裹 query.addCriteria(new Criteria().orOperator(criteriaList)); List<Price> priceList = mongoOperations.find(query, Price.class);
效果说明
修正后的代码会生成与预期一致的MongoDB查询结构:每个ItemDto对应的三个条件会被$and包裹,所有$and条件再被外层的$or包裹,完全符合需求,同时避免了原有的错误。
内容的提问来源于stack exchange,提问作者psprogrammer
相关产品推荐
相关产品推荐

