Mongodb 按嵌入字段和计数分组

Mongodb 按嵌入字段和计数分组,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一个集合,其中的文档字段为“投票”:[{id:“bob”,投票:“yes”},id:“mary”,投票:“no”}]。我想知道,对于每个人的id,他们在投票yes时出现的文档数量 到目前为止,我试过的是这个,但它不起作用;相反,它似乎是根据投票数和ID进行分组 db.votecol.aggregate([ {"$group": {"_id": {"id": "$votes.id"}, "voteCount": {"$sum": 1}}} ]) 您需要首先使用运算符,因为当它应用于列

我有一个集合,其中的文档字段为“投票”:[{id:“bob”,投票:“yes”},id:“mary”,投票:“no”}]。我想知道,对于每个人的
id
,他们在投票
yes
时出现的文档数量

到目前为止,我试过的是这个,但它不起作用;相反,它似乎是根据投票数和ID进行分组

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

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

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

作为后续问题的更新,您可以使用操作符在之前和之后过滤通过管道的文档,以统计“是”或“否”的选票。对于奖励积分,您可以利用管道步骤中的运算符,根据嵌入的投票字段值计算计数:

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 ]
                }
            }
        }
    }
])

是否可以只计算“是”或“否”的选票,而不计算其他选票?放卷前的匹配与放卷后的匹配有什么区别?区别在于将
$match
阶段放在管道的开头,聚合可以使用索引以及查询集合来限制进入管道的文档数量。因为聚合操作只需要集合中的数据子集,
$unwind
之前的
$match
阶段将限制在管道开头输入的文档。在
$unwind
之后,需要另一个
$match
阶段,以便从展开的数组中筛选文档。它看起来像是
投票。投票
之前不应该有
$
it(语法错误)--删除它似乎会产生所需的结果。@Hatshepsut我很抱歉,你说得对,它不应该以$作为前缀,我已经更新了答案。