繁体   English   中英

查询MongoDb以从引用ID数组的集合中获取计数

[英]Query MongoDb to get counts from collection on array of reference id

我有3个收藏:1。用户2.帖子3.行动

我的收藏品如下:

用户:

{ 
    "_id" : ObjectId("57ee65fef5a0c032877725db"), 
    "fbId" : "EAAXZA4sZCZBKmgBAKe0JpJPrp7utWME6xbHT9yFD", 
    "name" : "Aftab", 
    "email" : "xxxe@hotmail.com", 
    "gender" : "male", 
    "__v" : NumberInt(0), 
    "updatedAt" : ISODate("2016-10-10T05:11:35.344+0000"), 
    "score" : NumberInt(90)
}

动作:

{ 
    "_id" : ObjectId("57f7a0ba3a603627658afdd3"), 
    "updatedAt" : ISODate("2016-10-07T13:18:50.815+0000"), 
    "createdAt" : ISODate("2016-10-07T13:18:50.815+0000"), 
    "userId" : ObjectId("57ee65fef5a0c032877725db"), 
    "postId" : ObjectId("57f4b5e98899081203883a1b"), 
    "type" : "like"
}
{ 
    "_id" : ObjectId("57f7a0ba3a603627658afdd4"), 
    "updatedAt" : ISODate("2016-10-07T13:18:50.815+0000"), 
    "createdAt" : ISODate("2016-10-07T13:18:50.815+0000"), 
    "userId" : ObjectId("57ee65fef5a0c032877725db"), 
    "postId" : ObjectId("57f4b5d58899081203883a1a"), 
    "type" : "dismiss"
}

帖子:

{ 
    "_id" : ObjectId("57f24593e272b5199e9351b9"), 
    "imgFileLocation" : "http://xxxx/buybye-platform/uploads/image-1475495315229", 
    "description" : "cool cool", 
    "title" : "Bad Image ", 
    "userId" : ObjectId("57f21e3d0b787d0f7ad76dd0"), 
    "__v" : NumberInt(0)
}
{ 
    "_id" : ObjectId("57f4b5d58899081203883a1a"), 
    "imgFileLocation" : "http://xxx/buybye-platform/uploads/image-1475655125125", 
    "description" : "cool & cool", 
    "title" : "Good Image", 
    "userId" : ObjectId("57f21e3d0b787d0f7ad76dd0"), 
    "__v" : NumberInt(0)
}

用户可以创建帖子,其他用户可以对这些帖子执行操作

posts集合有userId的引用,action集合有userId(执行该操作的人),postId(在哪个帖子上)和action-type(如/ dislike / dismiss)的ref

我需要查询以获取在特定用户帖子上执行的所有操作

我能够获得针对用户的所有帖子,这非常简单并且是一个数组。 现在我需要在这个posts数组的每个帖子上执行所有操作。

如果您想要一个利用聚合框架的解决方案,您可以使用从MongoDB v3.2开始引入的$lookup阶段。

例如,如果要返回包含帖子详细信息的结果集以及在该特定帖子上执行的所有操作的数组,则可以运行以下聚合查询:

/*
 * QUERY #1
 */
db.posts.aggregate([
    {
        $lookup: {
            from: 'actions',
            localField: '_id',
            foreignField: 'postId',
            as: 'post_actions'
        }
    }
]);

/*
 * RESULT SET #1
 */
{
    "_id" : ObjectId("57ff4512a134e614a7178c1d"),
    "imgFileLocation" : "http://xxxx/buybye-platform/uploads/image-1475495315229",
    "description" : "cool cool",
    "title" : "Bad Image ",
    "userId" : ObjectId("57f21e3d0b787d0f7ad76dd0"),
    "__v" : 0,
    "post_actions" : [
        {
            "_id" : ObjectId("57ff4563a134e614a7178c1e"),
            "updatedAt" : ISODate("2016-10-07T13:18:50.815Z"),
            "createdAt" : ISODate("2016-10-07T13:18:50.815Z"),
            "userId" : ObjectId("57ee65fef5a0c032877725db"),
            "postId" : ObjectId("57ff4512a134e614a7178c1d"),
            "type" : "like"
        },
        {
            "_id" : ObjectId("57ff4564a134e614a7178c1f"),
            "updatedAt" : ISODate("2016-10-07T13:18:50.815Z"),
            "createdAt" : ISODate("2016-10-07T13:18:50.815Z"),
            "userId" : ObjectId("57ee65fef5a0c032877725db"),
            "postId" : ObjectId("57ff4512a134e614a7178c1d"),
            "type" : "share"
        }
    ]
}

否则,如果您只想检索特定帖子数组的操作,可以在聚合管道中添加$match阶段:

const postIdsArray = [
    ObjectId("57ff4512a134e614a7178c1d"),
    ObjectId("57ee65fef5a0c032877725db")
];

/*
 * QUERY #2
 */
db.posts.aggregate([
    {
        $match: {
            _id: {
                $in: postIdsArray
            }
        }
    },
    {
        $lookup: {
            from: 'actions',
            localField: '_id',
            foreignField: 'postId',
            as: 'post_actions'
        }
    }
]);

此外,如果您只想检索在帖子上执行的操作总数,可以添加$unwind阶段,然后$group所有结果:

/*
 * QUERY #3
 */
db.posts.aggregate([
    {
        $lookup: {
            from: 'actions',
            localField: '_id',
            foreignField: 'postId',
            as: 'post_actions'
        }
    },
    {
        $unwind: '$post_actions'
    },
    {
        $group: {
            _id: '$_id',
            posts: { $sum: 1 }
        }
    }
]);

/*
 * RESULT SET #3
 */
{ "_id" : ObjectId("57ff4512a134e614a7178c1d"), "posts" : 2 }

更新#1

如果您只想检索特定类型的操作(例如:喜欢,共享等),则可以在$lookup取消$unwind find阶段中检索到的post_actions数组后,在聚合管道中添加额外的$match阶段。

例如,第一个查询将变为:

/*
 * UPDATED QUERY #1
 */
db.posts.aggregate([
    {
        $lookup: {
            from: 'actions',
            localField: '_id',
            foreignField: 'postId',
            as: 'post_actions'
        }
    },
    {
        $unwind: '$post_actions'
    },
    {
        $match: {
            "post_actions.type": 'like'
        }  
    }
]);

第二个查询将变为:

const postIdsArray = [
    ObjectId("57ff4512a134e614a7178c1d"),
    ObjectId("57ee65fef5a0c032877725db")
];

/*
 * UPDATED QUERY #2
 */
db.posts.aggregate([
    {
        $match: {
            _id: {
                $in: postIdsArray
            }
        }
    },
    {
        $lookup: {
            from: 'actions',
            localField: '_id',
            foreignField: 'postId',
            as: 'post_actions'
        }
    },
    {
        $unwind: '$post_actions'
    },
    {
        $match: {
            "post_actions.type": 'like'
        }
    }
]);

第三个查询将成为:

/*
 * UPDATED QUERY #3
 */
db.posts.aggregate([
    {
        $lookup: {
            from: 'actions',
            localField: '_id',
            foreignField: 'postId',
            as: 'post_actions'
        }
    },
    {
        $unwind: '$post_actions'
    },
    {
        $match: {
            "post_actions.type": 'like'
        }
    },
    {
        $group: {
            _id: '$_id',
            posts: { $sum: 1 }
        }
    }
]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM