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

我共有3个集合:1.用户2.职位3.行动

我的collections看起来像这样:

用户:

{ "_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" } 

post:

 { "_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) } 

用户可以创buildpost,其他用户可以在这些post上执行操作

post集合具有userId和操作集合的引用具有userId(谁执行该操作),postId(关于哪个post)和操作types(喜欢/不喜欢/解雇)

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

我已经能够得到所有的post对用户,这是非常简单的,是一个数组。 现在我需要在这个post数组的每个post上执行所有的操作。

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

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

 /* * 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" } ] } 

否则,如果只想检索特定数量的post的操作,则可以在聚合pipe道中添加$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' } } ]); 

此外,如果您只想检索在post上执行的操作的总数,则可以添加$unwind阶段,然后$group所有结果$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

如果只想检索某个特定types的操作(例如:like,share等),可以在$unwind$lookup阶段中检索到的post_actions数组之后,在聚合pipe道中添加一个额外的$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 } } } ]);