Mongo Aggregation Pipeline $查找嵌套的嵌入式文档和$ project

时间:2016-08-16 03:42:18

标签: mongodb mongodb-query aggregation-framework mgo

我有两个集合users和`groups。让我们假设这些集合目前有以下数据。

users集合包含以下文档

{  
   "_id":"57a944390b1acf0d069388c1",
   "first":"John",
   "last":"Smith",
   "email":"John.Smith@gmail.com",
   "groups":[  
      {  
         "id":"57aab09c0b1acf135a6b6856",
         "name":"Group A"
      },
      {  
         "id":"57aab0ed0b1acf135a6b6857",
         "name":"Group B"
      },
      {  
         "id":"57b008be31a5a202ee4ff47b",
         "name":"Group C"
      }
   ]
}

groups集合包含以下两个文档

[  
   {  
      "_id":"57aab0ed0b1acf135a6b6857",
      "name":"Group B",
      "requests":[  
         {  
            "_id":"57b14b1831a5a2756fbc9873",
            "description":"Request A",
            "denied_requests":[ ]
         }
      ]
   }   {  
      "_id":"57b008be31a5a202ee4ff47b",
      "name":"Group C",
      "requests":[  
         {  
            "_id":"57b14c2131a5a2756fbc9874",
            "description":"Request B",
            "denied_requests":[ ]
         },
         {  
            "_id":"57b14e3131a5a2756fbc9875",
            "description":"Request C",
            "denied_requests":[  
               "57a944390b1acf0d069388c1"
            ]
         }
      ]
   }
]

我需要做的是使用聚合管道查询用户的所有请求,排除用户拒绝的请求。

我认为这将包含以下 psudo 步骤,并将user_id作为问题的输入。

    用户$match字段上的
  • _id
  • $project来自上一步结果的小组id
  • $lookup使用id $project users.groups_id的{​​{1}} groups
  • {li} $match requests根据请求在denied_requests数组中没有当前用户ID。

示例输入

对此的示例输入将是57a944390b1acf0d069388c1,代表用户_id

示例输出

此示例输出将是以下用户未拒绝的请求列表。

[
       {  
          "_id":"57b14b1831a5a2756fbc9873",
          "description":"Request A",
          "denied_requests":[]
       },
       {  
          "_id":"57b14c2131a5a2756fbc9874",
          "description":"Request B",
          "denied_requests":[ ]
       }   
]

1 个答案:

答案 0 :(得分:1)

运行以下管道,它应该会给你想要的结果:

var userId = "57a944390b1acf0d069388c1";
db.users.aggregate([
    { "$match": { "_id": userId } },
    { "$unwind": "$groups" },
    {
        "$lookup": {
            "from": "groups",
            "localField": "groups.id",
            "foreignField": "_id",
            "as": "group"
        }
    },
    { "$unwind": "$group" },
    {
        "$project": {
            "requests": {
                "$filter": {
                    "input": "$group.requests",
                    "as": "item",
                    "cond": { "$not": { 
                        "$setIsSubset": [ 
                            [userId], "$$item.denied_requests" 
                        ] 
                    } }
                }
            }
        }
    },
    { "$unwind": "$requests" },
    {
        "$project": {
            "_id": "$requests._id",
            "description": "$requests.description",
            "denied_requests": "$requests.denied_requests"
        }
    }
])