mongodb $查找带有投影的数组中的嵌套对象

Posted

技术标签:

【中文标题】mongodb $查找带有投影的数组中的嵌套对象【英文标题】:mongodb $lookup for nested object in array with projection 【发布时间】:2021-01-28 08:58:26 【问题描述】:

我在聚合管道中使用 $lookup 时遇到问题。

我有 2 个收藏,membersmessages

成员:

_id, FirstName, LastName, Email, ...

消息


  _id:ObjectId('xxx'),
  createdBy:ObjectId(''),
  ...
  threads:[
      message:'' , attachments:[] , from:ObjectId , to:[status:'Read' , recipient:ObjectId] ]

我想做的是,

to:[status:'Read' , recipient:ObjectId] 中查找每个收件人,并从成员集合中填充姓名和电子邮件。

我尝试了很多不同的东西,比如这个; //

db.messages.aggregate([
     
                '$lookup': 
                    'from': 'members',
                    'let': 
                        'memberId': '$threads.to.recipient'
                    ,
                    'pipeline': [
                        
                            '$match': 
                                '$expr': 
                                    '$eq': [
                                        '$$memberId', '$members._id'
                                    ]
                                
                            
                        ,
                        $project: FirstName: 1, _id: 1, LastName: 1, Email: 1
                    ],
                    'as': 'members'
                
            
    ]

包括这个在内的许多不同查询总是为成员返回 []('as': 'members')。

只是为了测试我厌倦了猫鼬和 .populate('threads.to.recipient','FirstName') 工作得很好。但我不能为此使用 mongoose,我必须使用 MongoDB 的本机 nodejs 驱动程序。

对此的任何建议将不胜感激......

【问题讨论】:

请以 mongo shell-executable 格式添加示例数据。 【参考方案1】:

在执行 $lookup 之前,您必须使用 $unwind 来展平 threads 数组的结构

db.messages.aggregate([
  
    $unwind: "$threads"
  ,
  
    $unwind: "$threads.to"
  ,
  
    $lookup: 
      from: "members",
      let: 
        memberId: "$threads.to.recipient"
      ,
      as: "members",
      pipeline: [
        
          $match: 
            $expr: 
              $eq: [
                "$$memberId",
                "$_id"
              ]
            
          
        ,
        
          $project: 
            FirstName: 1,
            _id: 1,
            LastName: 1,
            Email: 1
          
        
      ]
    
  
])

See the working example in MongoDB Playground

如果您不想使用 $unwind,请尝试以下查询:

db.messages.aggregate([
  
    "$lookup": 
      "from": "members",
      "localField": "threads.to.recipient",
      "foreignField": "_id",
      "as": "members"
    
  
])

See the working example in MongoDB Playground

【讨论】:

谢谢,扁平化线程的结构工作了。我必须使用 $unwind,因为使用 localField 和 foreignField 进行简单查找不允许我从成员中投射字段。

以上是关于mongodb $查找带有投影的数组中的嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB查询:如何查找嵌套对象中的字符串

通过聚合中的索引投影嵌套数组字段值

带有 elemMatch 的 MongoDB 查询,用于从对象内部匹配嵌套数组数据 [重复]

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

MongoDb - 在嵌套数组中查找特定的 obj

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