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

MongoDB聚合管道查询:获取父文档及其一级子文档

问题描述

我有一个名为things的MongoDB集合,包含以下文档:

[
  {
    "_id": 1,
    "name": "one",
    "others": [2, 3]
  },
  {
    "_id": 2,
    "name": "two"
  },
  {
    "_id": 3,
    "name": "three"
  },
  {
    "_id": 4,
    "name": "four"
  }
]

其中第一个文档通过others数组构成树形结构,数组里是其子文档的_id。我需要编写一个查询,返回扁平的文档列表:第一个是父文档,后面跟着others数组里对应的直接子文档(不需要递归)。比如传入_id=1时,预期结果是:

[
  {
    "_id": 1,
    "name": "one",
    "others": [2, 3]
  },
  {
    "_id": 2,
    "name": "two"
  },
  {
    "_id": 3,
    "name": "three"
  }
]

我尝试了下面的聚合语句,但报错$in needs an array:

db.things.aggregate([{
  $match: { _id: 1 }
}, {
  $match: { _id: { $in: '$others'}}
}
])

请问正确的查询语法是什么?


解决方案

你之前的写法错误在于第二个$match阶段无法引用管道前序阶段的字段值——$match是针对整个集合的全局过滤,它会把'$others'当成普通字符串而非数组,所以才会报$in needs an array的错误。

可以通过聚合管道的$lookup+$concatArrays组合实现需求,具体写法如下:

db.things.aggregate([
  // 1. 匹配父文档
  { $match: { _id: 1 } },
  // 2. 关联查询子文档,存入children字段
  {
    $lookup: {
      from: "things",
      localField: "others",
      foreignField: "_id",
      as: "children"
    }
  },
  // 3. 把父文档和子数组合并成一个新数组
  {
    $project: {
      docs: { $concatArrays: [[$$ROOT], "$children"] }
    }
  },
  // 4. 展开数组为单个文档
  { $unwind: "$docs" },
  // 5. 将每个数组元素转为根文档,同时移除多余的children字段
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          "$docs",
          { children: "$$REMOVE" }
        ]
      }
    }
  }
])

执行逻辑说明:

  1. $match定位到_id=1的父文档;
  2. $lookup根据父文档的others数组,从things集合中查询对应的子文档,结果存在children数组里;
  3. $concatArrays把父文档(用[$$ROOT]转成单元素数组)和children数组合并成一个新数组docs;
  4. $unwind将docs数组拆分成单个文档;
  5. $replaceRoot把每个docs元素转为根文档,同时用$$REMOVE去掉临时生成的children字段,恢复原文档结构。

另一种简化写法(如果不需要严格保证父文档在前):

如果你对结果顺序没有强制要求,也可以直接用$or条件一次查询:

// 先获取父文档的others数组,再组合查询条件
const parent = db.things.findOne({ _id: 1 });
db.things.find({
  $or: [
    { _id: 1 },
    { _id: { $in: parent.others } }
  ]
})

这种写法需要两次查询,但代码更简洁,适合对顺序要求不高的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:37:18