如何使用 mongodb 聚合来通过 $lookup 丰富 objects?

How to use mongodb aggregate to enrich objects with $lookup?

我正在使用 Pymongo 运行 根据我们的 Mongodb 聚合管道。

我有以下 collections:

用户

{
  _id: 1,
  name: 'John Doe',
  age: 30
},
{
  _id: 2,
  name: 'Jane Doe',
  age: 20
}

地点

{
  _id: 10,
  name: 'Miami'
},
{
  _id: 20,
  name: 'Orlando'
}

联系人

{
  _id: 100,
  contacts: [
    {
      user_id: 1,
      location_id: 10,
    },
    {
      user_id: 2,
      location_id: 20,
    }
  ]
}

作为聚合管道的结果,我需要:

{
  _id: 100,
  contacts: [
    {
      user_id: 1,
      user_name: 'John Doe',
      user_age: 30,
      location_id: 10,
      location_name: 'Miami'
    },
    {
      user_id: 2,
      user_name: 'Jane Doe',
      user_age: 20,
      location_id: 20,
      location_name: 'Orlando'
    }
  ]
}

我尝试了一些使用“$lookup”的查询,但我只是得到了一个新数组,而不是将值放在同一个 array/object.

怎样才能得到想要的结果?

您可以使用此聚合查询:

  • 首先$unwind解构数组并获取要加入的值
  • 然后两个 $lookup 连接值并创建数组 userslocations.
  • 由于使用了_id,所以你想要的数组中的值是第一个(它应该只有一个值,但如果存在多个则为重复值),所以你可以使用$arrayElemAt.
  • 然后$project得到你想要的字段名
  • $group 重新组合值。
db.contacts.aggregate([
  {
    "$unwind": "$contacts"
  },
  {
    "$lookup": {
      "from": "users",
      "localField": "contacts.user_id",
      "foreignField": "_id",
      "as": "users"
    }
  },
  {
    "$lookup": {
      "from": "locations",
      "localField": "contacts.location_id",
      "foreignField": "_id",
      "as": "locations"
    }
  },
  {
    "$set": {
      "users": {
        "$arrayElemAt": [
          "$users",
          0
        ]
      },
      "locations": {
        "$arrayElemAt": [
          "$locations",
          0
        ]
      }
    }
  },
  {
    "$project": {
      "contacts": {
        "user_id": 1,
        "location_id": 1,
        "user_name": "$users.name",
        "user_age": "$users.age",
        "location_name": "$locations.name"
      }
    }
  },
  {
    "$group": {
      "_id": "$_id",
      "contacts": {
        "$push": "$contacts"
      }
    }
  }
])

示例here