【问题标题】:MongoDB: How to populate the nested object with lookup query?MongoDB:如何使用查找查询填充嵌套对象?
【发布时间】:2023-03-12 03:02:01
【问题描述】:

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

DB 集合结构是这样的:

{
  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'}
}]

任何帮助将不胜感激。

【问题讨论】:

    标签: mongodb mongoose aggregation-framework nosql-aggregation


    【解决方案1】:

    试试这个:

    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] } }
            }
        }
    ]);
    

    【讨论】:

      【解决方案2】:
      • $unwind解构recipients数组
      • $lookup 用户收藏recipients.userId
      • $unwind解构recipients.userId数组
      • $lookup 用户收藏sender
      • $unwind解构sender数组
      • $group by _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

      【讨论】:

        猜你喜欢
        • 2015-04-08
        • 2021-01-24
        • 1970-01-01
        • 1970-01-01
        • 2017-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多