【问题标题】:mongodb - Merge object arrays based on keymongodb - 基于键合并对象数组
【发布时间】:2022-12-18 01:55:50
【问题描述】:

在 mongodb 数据库中,我有以下数据:

// db.people
[
  {
    _id: ObjectId("..."),
    id: 111111111,
    name: "George",
    relatedPeople: [{ id: 222222222, relation: "child" }],
    // A bunch of other data I don't care about
  },
  {
    _id: ObjectId("..."),
    id: 222222222,
    name: "Jacob",
    relatedPeople: [{ id: 111111111, relation: "father" }],
    // A bunch of other data I don't care about
  },
  {
    _id: ObjectId("..."),
    id: 333333333,
    name: "some guy",
    relatedPeople: [],
    // A bunch of other data I don't care about
  },
]

我想查询人员,只选择我显示的字段,但在relatedPeople (id + relation + name) 中有额外数据

所以所需的输出将是:

[
  {
    _id: ObjectId("..."),
    id: 111111111,
    name: "George",
    relatedPeople: [{ id: 222222222, relation: "child", name: "Jacob" }],
  },
  {
    _id: ObjectId("..."),
    id: 222222222,
    name: "Jacob",
    relatedPeople: [{ id: 111111111, relation: "father", name: "George" }],
  },
  {
    _id: ObjectId("..."),
    id: 333333333,
    name: "some guy",
    relatedPeople: [],
  },
]

我可以得到一些东西,使用此查询:

db.people.aggregate([
  // { $match: { /** ... */ }, },
  {
    $lookup: {
      from: "people",
      let: { relatedPeopleIds: "$relatedPeople.id" },
      pipeline: [
        { $match: { $expr: { $in: ["$id", "$$relatedPeopleIds"] } } },
        {
          $project: {
            id: 1,
            name: 1,
          },
        },
      ],
      as: "relatedPeople2",
    },
  },
  {
    $project: {
      id: 1,
      name: 1,
      relatedPeople: 1,
      relatedPeople2: 1,
    }
  }
]);

但是数据分为两个字段。我想通过 id 合并数组中的每个对象,并将结果数组放在 relatedPeople

我找到了this question,但是合并是在一个范围内完成的,并且使用了我不能使用的$arrayElementAt
我也试过查看this question,但我无法得到工作的答案(一直得到空结果)

【问题讨论】:

  • 为什么不能用$arrayElementAt
  • @nimrod serok 我不知道 relatedPeople 和 relatedPeople2 的顺序每次都一样,我不认为

标签: mongodb


【解决方案1】:

您可以使用 $arrayElementAt$indexOfArray 添加一步:

db.people.aggregate([
  // { $match: { /** ... */ }, },
  {$project: {id: 1, name: 1, relatedPeople: 1}},
  {$lookup: {
      from: "people",
      let: { relatedPeopleIds: "$relatedPeople.id" },
      pipeline: [
        { $match: { $expr: { $in: ["$id", "$$relatedPeopleIds"] } } },
        {
          $project: {
            id: 1,
            name: 1,
          },
        },
      ],
      as: "relatedPeople2",
    },
  },
  {$set: {
      relatedPeople: {$map: {
          input: "$relatedPeople",
          in: {$mergeObjects: [
              "$$this",
              {$arrayElemAt: [
                  "$relatedPeople2",
                  {$indexOfArray: ["$relatedPeople2.id", "$$this.id"]}
                ]}
          ]}
      }}
  }},
  {$unset: "relatedPeople2"}
])

查看它在playground example 上的工作原理

【讨论】:

    猜你喜欢
    • 2018-04-01
    • 2021-01-27
    • 1970-01-01
    • 2021-09-19
    • 2015-06-08
    • 1970-01-01
    • 2014-03-03
    • 2018-05-03
    相关资源
    最近更新 更多