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

如何编写MongoDB聚合查询并在SpringBoot中实现父子文档分组?

针对你的需求,以下是MongoDB原生查询和SpringBoot中的具体实现方案:

MongoDB 原生查询实现

使用聚合管道完成自关联分组,直接在MongoShell中执行即可得到目标结构:

db.your_collection_name.aggregate([
  // 自关联查询子文档:将parentID等于当前文档id的文档存入children数组
  {
    $lookup: {
      from: "your_collection_name",
      localField: "id",
      foreignField: "parentID",
      as: "children"
    }
  },
  // 筛选父级文档:仅保留parentID以Top_开头的记录
  {
    $match: {
      parentID: { $regex: "^Top_" }
    }
  },
  // 整理输出结构:只保留name和children字段,去除冗余的_id
  {
    $project: {
      _id: 0,
      name: 1,
      // 可选:如果需要过滤子文档的字段,用$map自定义输出,否则直接写children:1
      children: {
        $map: {
          input: "$children",
          as: "child",
          in: {
            id: "$$child.id",
            name: "$$child.name",
            age: "$$child.age"
          }
        }
      }
    }
  }
])

执行后会返回类似如下格式的结果:

[
  {
    "name": "A",
    "children": [
      {"id": 3, "name": "Aa", "age": 12},
      {"id": 3, "name": "Ab", "age": 8}
    ]
  },
  {
    "name": "B",
    "children": [
      {"id": 2, "name": "Ba", "age": 5},
      {"id": 5, "name": "Ba", "age": 5},
      {"id": 6, "name": "Ba", "age": 7}
    ]
  }
]
SpringBoot 实现方案

1. 定义实体类

首先创建对应集合的实体(假设集合名为person):

import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;

@Document(collection = "person")
public class Person {
    private Integer id;
    private String name;
    private Integer age;
    private String parentID;
    private List<Person> children; // 存储子文档列表

    // 手动生成getter、setter,或使用Lombok的@Data注解
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
    public String getParentID() { return parentID; }
    public void setParentID(String parentID) { this.parentID = parentID; }
    public List<Person> getChildren() { return children; }
    public void setChildren(List<Person> children) { this.children = children; }
}

2. 方式一:使用 MongoTemplate

通过MongoTemplate构建聚合管道:

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class PersonService {
    private final MongoTemplate mongoTemplate;

    // 构造注入MongoTemplate
    public PersonService(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    public List<Person> getParentsWithChildren() {
        Aggregation aggregation = Aggregation.newAggregation(
            // 自关联查询子文档
            Aggregation.lookup("person", "id", "parentID", "children"),
            // 筛选父级文档
            Aggregation.match(Criteria.where("parentID").regex("^Top_")),
            // 投影需要的字段,排除_id
            Aggregation.project("name", "children").andExclude("_id")
        );

        AggregationResults<Person> results = mongoTemplate.aggregate(aggregation, "person", Person.class);
        return results.getMappedResults();
    }
}

3. 方式二:使用 MongoRepository + @Aggregation 注解

直接在Repository接口中定义聚合查询:

import org.springframework.data.mongodb.repository.Aggregation;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;

public interface PersonRepository extends MongoRepository<Person, Integer> {
    @Aggregation(pipeline = {
        "{$lookup: {from: 'person', localField: 'id', foreignField: 'parentID', as: 'children'}}",
        "{$match: {parentID: {$regex: '^Top_'}}}",
        "{$project: {_id: 0, name: 1, children: 1}}"
    })
    List<Person> findParentsWithChildren();
}

在业务代码中直接注入PersonRepository并调用findParentsWithChildren()方法即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:06:29