如何将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
相关产品推荐
相关产品推荐

