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

Posted

技术标签:

【中文标题】MongoDB:如何使用查找查询填充嵌套对象?【英文标题】:MongoDB: How to populate the nested object with lookup query? 【发布时间】:2021-05-21 01:39:09 【问题描述】:

我正在获取对其他集合有一些嵌套引用的记录列表,我想使用 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'
]

任何帮助将不胜感激。

【问题讨论】:

【参考方案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

【讨论】:

以上是关于MongoDB:如何使用查找查询填充嵌套对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用nodejs从我的数据模型中的嵌套对象填充mongodb中的数据集合?

mongoDB对嵌套对象数组的聚合查找

如何查找与嵌套键 laravel mongodb jenssegers 匹配的记录

javascript 如何查询MongoDB中的嵌套对象?

Mongodb用populate返回更新的对象

MongoDB 条件查询和排序