MongoDB: 如何使用查找查询填充嵌套对象?

MongoDB: How to populate the nested object with lookup query?

我正在获取对其他集合有一些嵌套引用的记录列表,我想使用 mongoDb 聚合查找查询填充对象数组内的嵌套 ObjectId。

数据库集合结构是这样的:

{
  subject: {type: String},
  body: {type: String},
  recipients: [{
    userId: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
    stutus: {type: String, enum: ['pending','accepted','rejected'], default:'pending'}
  }],
  sender: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}
}

我期待的是:

[{
  subject: 'Some subject here.',
  body: 'Lorem ipsum dolor emit set',
  recipients: [{
    userId: {firstName: 'John', lastName: 'Doe'},
    status: 'accepted'
  },{
    userId: {firstName: 'Jane', lastName: 'Doe'},
    status: 'accepted'
  }],
  sender: {firstName: 'Jacobs', 'lastName': 'Doe'}
},{
  subject: 'Some subject here.',
  body: 'Lorem ipsum dolor emit set',
  recipients: [{
    userId: {firstName: 'Jane', lastName: 'Doe'},
    status: 'rejected'
  },{
    userId: {firstName: 'John', lastName: 'Doe'},
    status: 'accepted'
  }],
  sender: {firstName: 'Jacobs', 'lastName': 'Doe'}
}]

如有任何帮助,我们将不胜感激。

  • $unwind解构recipients数组
  • $lookup 包含 recipients.userId
  • 的用户集合
  • $unwind解构recipients.userId数组
  • $lookup 包含 sender
  • 的用户集合
  • $unwind解构sender数组
  • $group_id 重建 recipients 数组
db.mails.aggregate([
  { $unwind: "$recipients" },
  {
    $lookup: {
      from: "users",
      localField: "recipients.userId",
      foreignField: "_id",
      as: "recipients.userId"
    }
  },
  { $unwind: "$recipients.userId" },
  {
    $lookup: {
      from: "users",
      localField: "sender",
      foreignField: "_id",
      as: "sender"
    }
  },
  { $unwind: "$sender" },
  {
    $group: {
      _id: "$_id",
      recipients: { $push: "$recipients" },
      subject: { $first: "$subject" },
      body: { $first: "$body" },
      sender: { $first: "$sender" }
    }
  }
])

Playground

试试这个:

db.emails.aggregate([
    { $unwind: "$recipients" },
    {
        $lookup: {
            from: "users",
            let: { userId: "$recipients.userId", status: "$recipients.stutus" },
            pipeline: [
                {
                    $match: {
                        $expr: { $eq: ["$_id", "$$userId"] }
                    }
                },
                {
                    $project: {
                        "_id": 0,
                        "userId": {
                            "firstName": "$firstName",
                            "lastName": "$lastName",
                        },
                        "status": "$$status"
                    }
                }
            ],
            as: "recipient"
        }
    },
    {
        $lookup: {
            from: "users",
            let: { userId: "$sender" },
            pipeline: [
                {
                    $match: {
                        $expr: { $eq: ["$_id", "$$userId"] }
                    }
                },
                {
                    $project: {
                        "_id": 0,
                        "firstName": 1,
                        "lastName": 1
                    }
                }
            ],
            as: "sender"
        }
    },
    {
        $group: {
            _id: "$_id",
            subject: { $first: "$subject" },
            body: { $first: "$body" },
            recipients: { $push: { $arrayElemAt: ["$recipient", 0] } },
            sender: { $first: { $arrayElemAt: ["$sender", 0] } }
        }
    }
]);