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

MongoDB新手求助:聚合查询中基于parent_id生成同组name数组

解决MongoDB聚合中按parent_id生成name数组的问题

首先,你当前的聚合逻辑有个关键问题:按$_id分组的话,每个分组只能拿到单个文档的数据,根本没法获取同parent_id下其他文档的name值。要实现需求,我们需要先拿到每个parent_id对应的所有name集合,再把这个集合关联回每个原始文档,最后通过$cond判断$check的值来设置item字段。

方法一:使用$setWindowFields(推荐,MongoDB 5.0+)

这种方法最简洁,不需要额外的分组和关联操作,直接通过窗口函数在每个文档中获取同parent_id的所有name:

const check = false; // 定义你的$check变量
db.getCollection('test').aggregate([
  // 为每个文档添加同parent_id的所有name数组
  {
    "$setWindowFields": {
      "partitionBy": "$parent_id",
      "output": {
        "parent_names": {
          "$addToSet": "$name",
          "window": {
            "documents": "unbounded preceding",
            "documents": "unbounded following"
          }
        }
      }
    }
  },
  // 根据check的值设置item字段
  {
    "$addFields": {
      "item": {
        "$cond": [
          check,
          "YES",
          "$parent_names" // 这里就是你要的ANSWER部分对应的逻辑
        ]
      }
    }
  }
])

方法二:兼容旧版本MongoDB(分组+关联)

如果你的MongoDB版本低于5.0,没法用窗口函数,可以先按parent_id分组收集name数组,再通过$lookup关联回原始文档:

const check = false;
db.getCollection('test').aggregate([
  // 分组得到每个parent_id对应的name数组
  {
    "$group": {
      "_id": "$parent_id",
      "names": { "$addToSet": "$name" }
    }
  },
  // 关联回原始文档,把names数组带回去
  {
    "$lookup": {
      "from": "test",
      "localField": "_id",
      "foreignField": "parent_id",
      "as": "docs"
    }
  },
  // 展开文档,恢复原始结构
  { "$unwind": "$docs" },
  // 设置item字段
  {
    "$addFields": {
      "item": {
        "$cond": [
          check,
          "YES",
          "$names" // 这里是ANSWER部分对应的内容
        ]
      },
      "_id": "$docs._id",
      "parent_id": "$docs.parent_id",
      "name": "$docs.name"
    }
  },
  // 清理不需要的字段
  { "$project": { "docs": 0 } }
])

适配你原始的聚合结构

如果你坚持要在你给出的$group结构里实现(虽然这种方式没必要,因为每个_id唯一),那你需要先通过$lookup提前获取同parent_id的name数组,再在$group里使用:

const check = false;
db.getCollection('test').aggregate([
  // 先关联获取同parent_id的name数组
  {
    "$lookup": {
      "from": "test",
      "localField": "parent_id",
      "foreignField": "parent_id",
      "as": "parent_docs"
    }
  },
  // 提取name数组
  {
    "$addFields": {
      "parent_names": { "$map": { "input": "$parent_docs", "as": "d", "in": "$$d.name" } }
    }
  },
  // 按_id分组(每个组仅单个文档)
  {
    "$group": {
      "_id": "$_id",
      "parent_id": { "$last": "$parent_id" },
      "name": { "$last": "$name" },
      "item": {
        "$last": {
          "$cond": [
            check,
            "YES",
            "$parent_names" // 这就是你要填的ANSWER部分
          ]
        }
      }
    }
  }
])

总结一下,你要的ANSWER部分的正确写法是"$parent_names"(前提是你已经通过窗口函数或关联操作得到了这个同parent_id的name数组)。

内容的提问来源于stack exchange,提问作者tnp.t

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:59:50