如何使用查找作为参考来获取 MongoDB 中的记录数

How to get a count of records in MongoDB using a Lookup as a Reference

我正在尝试构建一个投票系统。我有一个选择集合和一个投票集合

选择集合,显示 'poll1'

中可用的选择
_id:'1',
pollId:'poll1',
choice:'red'

_id:'2',
pollId:'poll1',
choice:'blue'

_id:'3',
pollId:'poll1'
choice:'green'

投票收集

_id:'a'
choiceId:'3'  // corresponds to the _id in the Choices collection
userId:'user1'  // id of the user who voted 

_id:'b'
choiceId:'3'
userId:'user2'

_id:'c'
choiceId:'1'
userId:'user3'

我希望能够计算投票中每个选项的票数。目前我对 Votes 集合有以下基本查询,其中 returns 只是选择的 ID 和投票数

[
    {
        '$match': {
            'pollId': pollId
        }
    }, {
        '$group': {
             '_id': '$choiceId', 
             'votes': {
                 '$sum': 1
             }
         }
    }
]

但是,我希望能够使用对 Choices 集合的查找作为参考 - 对于投票中的每个可用选项,获取该选项的 choiceId、choiceName 和票数选择.

从阅读文档来看,它似乎是这样的,但它只是 returns 该投票的所有选项的数组,以及总票数,而不是每个选项的票数

[
   {
       '$match': {
           'pollId': pollId
       }
   }, {
       '$lookup': {
            'from': 'choices', 
            'localField': 'pollId', 
            'foreignField': 'pollId', 
            'as': 'choiceData'
        }
   }, {
       '$group': {
           '_id': '$choiceData._id', 
           'votes': {
               '$sum': 1
           }
       }
    }
 ]

谁能解释一下如何获取以下结构的数据:

choiceId:'3', choice:'green', votes:2

choiceId:'1', choice:'red', votes:1

choiceId:'2', choice:'blue', votes:0

我们将不胜感激任何帮助。干杯,马特

您可以使用此聚合查询:

  • 首先 $match 您的投票名称(就像您一样)。
  • 然后使用$lookup合并集合。但是这里有一些事情可以做得更好:from 是另一个集合,localField 是集合中正在查找的字段,foreignField 是另一个集合。因此,您必须加入 votes 集合,其中 choices 集合中的字段 _idvotes 集合中的 choiceId 相同。
  • 最后$project得到你想要的值。在这种情况下,将 choiceId 设置为 _id,将 votes 设置为查找返回的结果数(即投票数)。
db.choices.aggregate([
  {
    "$match": {
      "pollId": "poll1"
    }
  },
  {
    "$lookup": {
      "from": "votes",
      "localField": "_id",
      "foreignField": "choiceId",
      "as": "choiceData"
    }
  },
  {
    "$project": {
      "_id": 0,
      "choice": 1,
      "choiceId": "$_id",
      "votes": {
        "$size": "$choiceData"
      }
    }
  }
])

示例here