You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:50:42