MongoDB单集合中按父文档group字段查询父子文档的方法
MongoDB父子文档聚合查询实现(Java Spring)
需求说明
同一集合中存储两类文档:
- 父文档:包含
_id、parent_id(通常设为null以标识父节点)、active、group字段 - 子文档:包含
id、parent_id(关联对应父文档的_id)、active字段,group值默认继承父文档
需要返回指定active值和指定group值的所有父文档,以及对应符合指定active值的子文档。
聚合实现步骤
- 匹配符合条件的父文档:筛选
parent_id为null、active等于目标值、group等于目标值的父文档 - 关联对应子文档:通过
$lookup关联集合中parent_id匹配父文档_id且active符合目标值的子文档 - 整理输出结构:将子文档列表嵌入父文档的
children字段中统一返回
Java Spring 代码实现
方式一:使用Spring Data MongoDB Aggregation API
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.AggregationOperation; import org.springframework.data.mongodb.core.aggregation.LookupOperation; import org.springframework.data.mongodb.core.query.Criteria; import java.util.List; // 假设父文档实体类为ParentDoc,包含children字段(类型为List<ChildDoc>) public List<ParentDoc> queryParentWithChildren(boolean targetActive, String targetGroup) { // 1. 匹配符合条件的父文档 AggregationOperation matchParents = Aggregation.match( Criteria.where("parent_id").is(null) .and("active").is(targetActive) .and("group").is(targetGroup) ); // 2. 关联符合条件的子文档 LookupOperation lookupChildren = LookupOperation.newLookup() .from("your_collection_name") // 替换为实际集合名称 .localField("_id") .foreignField("parent_id") .pipeline(Aggregation.match(Criteria.where("active").is(targetActive))) .as("children"); // 构建聚合管道并执行查询 Aggregation aggregation = Aggregation.newAggregation(matchParents, lookupChildren); return mongoTemplate.aggregate(aggregation, "your_collection_name", ParentDoc.class).getMappedResults(); }
方式二:直接使用BSON聚合语句(适用于复杂场景)
import org.bson.Document; import org.springframework.data.mongodb.core.MongoTemplate; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public List<Document> queryParentWithChildrenByBson(boolean targetActive, String targetGroup) { String aggregationPipeline = "[\n" + " {\n" + " $match: {\n" + " parent_id: null,\n" + " active: " + targetActive + ",\n" + " group: \"" + targetGroup + "\"\n" + " }\n" + " },\n" + " {\n" + " $lookup: {\n" + " from: \"your_collection_name\",\n" + " localField: \"_id\",\n" + " foreignField: \"parent_id\",\n" + " pipeline: [{ $match: { active: " + targetActive + " } }],\n" + " as: \"children\"\n" + " }\n" + " }\n" + "]"; List<Document> pipeline = Arrays.asList(Document.parse(aggregationPipeline)); return mongoTemplate.getCollection("your_collection_name").aggregate(pipeline).into(new ArrayList<>()); }
注意事项
- 请将代码中的
your_collection_name替换为实际的集合名称 - 如果父文档的
parent_id不是null而是特定标识值(如0),请修改matchParents中的匹配条件 - 实体类
ParentDoc和ChildDoc需与文档字段对应,确保映射正确
内容的提问来源于stack exchange,提问作者java12399900
相关产品推荐
相关产品推荐

