MongoDB:如何使用矩阵对同一集合进行两个并集

时间:2019-05-13 15:40:17

标签: mongodb

我有带有记录的用户记录,并与他们共享了帖子,即用户可以与其他用户共享这些记录。我需要能够仅获取或获取与他共享的帖子,并使用共享该帖子的用户的ID和该帖子的ID作为参考。

当我使用用户ID作为参考时,它可以工作,但是当我尝试将其与帖子ID结合使用时,它什么也没有得到,这是当我尝试仅使用帖子ID进行获取时发生的共享的帖子。

这就是记录的结构

{
    "_id" : ObjectId("5cd573b2bb9ad84f9bba2f74"),
    "name" : "name 4",
    "posts" : [ 
        {
            "_id" : ObjectId("5cd573b2bb9ad84f9bba2f72"),
            "name" : "post 1"
        }, 
        {
            "_id" : ObjectId("5cd573b2bb9ad84f9bba2f73"),
            "name" : "post 2"
        }
    ],
    "postSharedWithMe" : [ 
        {
            "user_id" : "5cd4aaedfcf8d8583cf97494",
            "post_id" : "5cd4aaedfcf8d8583cf97492"
        }, 
        {
            "user_id" : "5cd4aaedfcf8d8583cf97494",
            "post_id" : "5cd4aaedfcf8d8583cf97493"
        }
    ]
}

他以这种方式尝试咨询他们

db.users.aggregate([
    { "$match": { "_id": ObjectId("5cd573b2bb9ad84f9bba2f74") }},
    { $unwind:"$postSharedWithMe" },
    { $unwind:"$posts" },
    {
      $lookup:
         {
           from: "users",
           let: { 
              user_id: { "$toObjectId": "$postSharedWithMe.user_id"},
              post_id : { "$toObjectId": "$postSharedWithMe.post_id"}
           },

           pipeline: [
              { $match:
                 { $expr:
                    { $and:
                       [
                         { $eq: [ "$_id", "$$user_id" ] },
                         { $eq: [ "$posts._id", "$$post_id" ] }
                       ]
                    }
                 }
              },            
           ],
           as: "sharedPosts"
         }
    },
    { $unwind:"$sharedPosts" },
    { "$group": {
            "_id": "$_id",
            "sharedPosts": { "$push": "$sharedPosts" }
        }
    }
])

,结果如下: 在0ms内获取了0条记录

这就是我所期望的

{
    "_id" : ObjectId("5cd573b2bb9ad84f9bba2f74"),
    "name" : "username",
    "posts" : [ 
        {
            "_id" : ObjectId("5cd573b2bb9ad84f9bba2f72"),
            "name" : "post 1"
        }, 
        {
            "_id" : ObjectId("5cd573b2bb9ad84f9bba2f73"),
            "name" : "post 2"
        }
    ],
    "sharedPosts" : [ 
        {
            "_id" : ObjectId("id"),
            "name" : "shared post"
        }, 
        {
            "_id" : ObjectId("id"),
            "name" : "shared post"
        }
    ]
}

1 个答案:

答案 0 :(得分:0)

显然,我在引用共享帖子时需要先浏览所有帖子,其结果是一个数组,现在我只需要使$展开并与$ eq进行比较就可以了!

db.users.aggregate([
    { $match: { "_id": ObjectId("5cd573b2bb9ad84f9bba2f74") }},
    { $unwind: "$postSharedWithMe" },    
    {
      $lookup:
         {
           from: "users",
           let: { 
              user_id: { $toObjectId: "$postSharedWithMe.user_id"},
              post_id : { $toObjectId: "$postSharedWithMe.post_id"}
           },

           pipeline: [
              { $match:
                 { $expr:
                    { $and:
                       [
                         { $eq: [ "$$user_id", "$_id" ] },
                         { $in: ["$$post_id", "$posts._id" ] },                    
                       ]
                    }
                 }
              }, 
              { $unwind: "$posts" },
              { $match: { $expr: { $eq: [ "$posts._id", "$$post_id" ] } } },       
           ],
           as: "sharedPosts"
         }
    },
    { $unwind: "$sharedPosts" },
    { $group: {
            _id: "$_id",
            name: { "$first": "$name" },
            posts: { "$first": "$posts" },
            sharedPosts: { $push: 
                "$sharedPosts.posts" 
            }
        }
    }
])