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

如何将Mongoshell投影语句转换为Spring MongoTemplate投影实现

错误原因

你使用的nested()方法仅适用于提取单个嵌套文档的指定字段,而经过$group阶段后,result是一个包含多个文档的数组,结构不匹配导致无法正确提取字段,返回空列表。

正确实现方案

方案1(Spring Data MongoDB 3.2+ 版本,推荐)

高版本直接支持数组字段的子字段投影,写法和原生MongoDB语法逻辑完全对齐:

ProjectionOperation project = Aggregation.project()
    // 对result数组内的所有元素,只保留id、cID、level三个字段
    .and("result").project("id", "cID", "level")
    // 如果不需要返回group生成的_id字段,可加下面这行和原生查询逻辑完全一致
    .andExclude("_id");

方案2(低版本兼容方案)

如果使用的是3.2以下的版本,可通过数组Map算子手动构造投影逻辑:

ProjectionOperation project = Aggregation.project()
    .and(ArrayOperators.Map.itemsOf("result")
        .as("item")
        .andApply(context -> new Document()
            .append("id", "$$item.id")
            .append("cID", "$$item.cID")
            .append("level", "$$item.level")
        )
    ).as("result")
    .andExclude("_id");

完整聚合示例

你可以对照下面的完整代码检查所有阶段是否和原生逻辑一致:

Aggregation aggregation = Aggregation.newAggregation(
    // match阶段
    Aggregation.match(Criteria.where("id").is("1")),
    // graphLookup阶段
    Aggregation.graphLookup("pages")
        .startWith("cID")
        .connectFrom("parent")
        .connectTo("cID")
        .as("result")
        .depthField("level"),
    // unwind阶段,保留空数组
    Aggregation.unwind("result", true),
    // 按level升序排序
    Aggregation.sort(Sort.Direction.ASC, "result.level"),
    // 分组聚合结果
    Aggregation.group("id").push("result").as("result"),
    // 最终投影
    Aggregation.project().and("result").project("id", "cID", "level").andExclude("_id")
);

// 执行查询替换你的集合名和结果映射类即可
AggregationResults<YourResultDTO> result = mongoTemplate.aggregate(aggregation, "your_collection_name", YourResultDTO.class);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:24:03