按嵌入字段和计数分组

时间:2016-07-14 17:09:03

标签: mongodb mongodb-query aggregation-framework

我有一个包含字段"votes": [{id: "bob", vote: "yes"}, id: "mary", vote: "no"}]的文档的集合。对于每个人id,我希望他们以投票yes出现的文档数量。

到目前为止我尝试过的是这个,但它没有正常工作;相反,除了ids之外,它似乎按照投票数进行分组。

db.votecol.aggregate([
    {"$group": {"_id": {"id": "$votes.id"}, "voteCount": {"$sum": 1}}}
])

1 个答案:

答案 0 :(得分:3)

首先需要使用 $unwind 运算符,因为当它应用于列表数据字段时,它将为列表数据字段的每个元素生成一条新记录在哪个展开应用。它基本上使数据变平,以便您可以将其作为前一个管道中的单个文档进行处理。

db.votecol.aggregate([
    { "$unwind": "$votes" },
    { 
        "$group": {
            "_id": "$votes.id", 
            "voteCount": { "$sum": 1 }
        }
    }
])

作为对后续问题的更新,您可以过滤通过管道传输的文档,以计算“" yes"或"不"在 $match 之前和之后使用 $unwind 运算符。对于奖励积分,您可以利用 $cond 管道步骤中的 $group 运算符来根据嵌入的投票字段评估计数值:

db.votecol.aggregate([
    { "$match": { "votes.vote": { "$in": ["yes", "no"] } } },
    { "$unwind": "$votes" },
    { "$match": { "votes.vote": { "$in": ["yes", "no"] } } },
    { 
        "$group": {
            "_id": "$votes.id", 
            "voteCount": { "$sum": 1 },
            "yesCount": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$votes.vote", "yes" ] }, 1, 0 ]
                }
            },
            "noCount": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$votes.vote", "no" ] }, 1, 0 ]
                }
            }
        }
    }
])