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

MongoDB如何按公共字段分组并合并同组文档的指定字段内容

MongoDB 同字段分组拼接解决方案

你可以直接使用MongoDB自带的聚合管道实现需求,不需要额外依赖,完整查询语句如下:

db.collection.aggregate([
  // 按paragraph字段分组
  {
    $group: {
      _id: "$paragraph",
      // 取同组第一条文档的id作为分组后记录的id
      originalId: { $first: "$id" },
      // 将同组所有text字段存入数组
      textArr: { $push: "$text" }
    }
  },
  // 重构字段结构,拼接text数组为字符串
  {
    $project: {
      _id: 0,
      id: "$originalId",
      paragraph: "$_id",
      // 用空格拼接所有text,避免开头多余空格
      text: {
        $reduce: {
          input: "$textArr",
          initialValue: "",
          in: {
            $concat: [
              "$$value",
              { $cond: [{ $eq: ["$$value", ""] }, "", " "] },
              "$$this"
            ]
          }
        }
      }
    }
  },
  // 按id升序排序
  { $sort: { id: 1 } },
  // 可选:如果需要将结果持久化为新集合,添加$out阶段
  // { $out: "merged_paragraph" }
])

如果你期望最终结果的id是连续递增的1、2、3(和你给出的示例结果一致),可以在排序阶段后新增行号生成逻辑,替换原有id:

{
  $setWindowFields: {
    sortBy: { paragraph: 1 },
    output: { id: { $documentNumber: {} } }
  }
}

业务代码层实现(可选)

如果你不想用MongoDB聚合,也可以在业务代码中查询全量数据后手动分组处理,以Node.js为例:

// 查询所有文档
const allDocs = await db.collection.find().sort({ id: 1 }).toArray();
const paragraphMap = new Map();
const result = [];

allDocs.forEach(doc => {
  if (!paragraphMap.has(doc.paragraph)) {
    const newItem = {
      id: doc.id,
      paragraph: doc.paragraph,
      text: doc.text
    };
    paragraphMap.set(doc.paragraph, newItem);
    result.push(newItem);
  } else {
    paragraphMap.get(doc.paragraph).text += ` ${doc.text}`;
  }
});

// 如需生成连续id,直接遍历result赋值即可
// result.forEach((item, index) => item.id = index + 1)

最终得到的result数组即可直接作为接口响应返回。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:45:03