1

我共有3个集: 1.用户 2.帖子 3.行动查询的MongoDB摆脱集合计数的参考ID阵列

我的藏品看起来像这些:

用户:

{ 
    "_id" : ObjectId("57ee65fef5a0c032877725db"), 
    "fbId" : "EAAXZA4sZCZBKmgBAKe0JpJPrp7utWME6xbHT9yFD", 
    "name" : "Aftab", 
    "email" : "[email protected]", 
    "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) 
} 

用户可以创建的帖子,并且其他用户可以在这些帖子

帖集合具有用户id 和动作集合的参考执行操作具有用户id的REF(谁执行该操作),postId(在哪个帖子)和动作类型(喜欢/不喜欢/解雇)

我需要查询以获取所有在特定的用户帖子

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

+0

你愿意更新你的问题与集合中的一些示例文档以及期望的聚合的预期输出?这有助于澄清问题并鼓励高质量的答案。 – chridam

+0

你正在运行哪个MongoDB版本? – styvane

+0

mongodb v3.2 @Styvane –

回答

2

如果您想要一个利用聚合框架的解决方案,您可以使用从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阶段检索到的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 } 
     } 
    } 
]); 
+0

完美工作。 我将如何获得特定帖子的具体操作总数?说“喜欢”或“不喜欢” –

+1

@HaroonKhan我已经更新了所有3个示例查询的答案以满足您的要求。一探究竟 :) –