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

Mongo4.4.0下Reactive MongoTemplate聚合提示cursor选项必填错误如何解决?

问题原因

Spring Data MongoDB 3.2.x版本的ReactiveMongoTemplate会默认给所有响应式聚合请求自动添加cursor参数,但MongoDB 4.2+明确规定:如果聚合的最后一个阶段是$merge/$out这类写操作阶段,聚合请求不能携带cursor参数,二者冲突就触发了本次报错。你之前主动添加cursorBatchSize/cursor参数的操作反而会加重冲突。

解决方案

  • 第一步:调整聚合选项配置,禁用自动添加游标,同时标记聚合不需要返回输出
    核心配置是添加skipOutput(true),标记当前聚合为写操作、不需要返回结果集,框架会自动禁用cursor参数:

    AggregationOptions options = AggregationOptions.builder()
            .allowDiskUse(true)
            .skipOutput(true) 
            .build();
    
  • 第二步:调整方法返回值与调用逻辑
    $merge是写操作,执行完成后默认不会返回业务实体,如果你不需要获取写入后的文档,直接返回操作完成的信号即可;如果确实需要返回写入后的结果,需要在merge配置中添加returnNewDocuments(true),同时去掉skipOutput配置。
    无返回值的完整代码示例:

    public Mono<Void> someMethod(String param) {
        return reactiveMongoTemplate.aggregate(Aggregation.newAggregation(X.class,
                        Aggregation.match(Criteria.where("test").is(param)),
                        Aggregation.group("field")
                                .first("value").as("value")
                                .first("test").as("test"),
                        Aggregation.group()
                                .first("test").as("test")
                                .push(new BasicDBObject()
                                        .append("k", "$_id")
                                        .append("v", "$value")
                                )
                                .as("array"),
                        Aggregation.replaceRoot(
                                MergeObjects.merge(
                                        new BasicDBObject().append("_id", "$test"),
                                        ArrayToObject.arrayValueOfToObject("array")
                                )
                        ),
                        Aggregation.project(getFields()),
                        Aggregation.merge()
                                .into(MergeOperationTarget.collection("test"))
                                .on("id")
                                // 若需要返回写入后的新文档,加上下面这行,同时删除skipOutput配置
                                // .returnNewDocuments(true)
                                .build()
                ).withOptions(AggregationOptions.builder()
                        .allowDiskUse(true)
                        // 不需要返回结果就保留该配置,需要返回则删除
                        .skipOutput(true)
                        .build()), Test.class)
                // 不需要返回结果用then(),需要返回结果则保留single()
                .then();
    }
    
  • 第三步:检查嵌入式Mongo兼容版本
    你当前使用的flapdoodle嵌入式Mongo需要匹配4.4版本的协议,建议升级到de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.12.0及以上版本,避免模拟实例本身的兼容bug导致问题复现。

内容的提问来源于stack exchange,提问作者BrianM

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:24:00