我有一个包含字段"votes": [{id: "bob", vote: "yes"}, id: "mary", vote: "no"}]
的文档的集合。对于每个人id
,我希望他们以投票yes
出现的文档数量。
到目前为止我尝试过的是这个,但它没有正常工作;相反,除了ids之外,它似乎按照投票数进行分组。
db.votecol.aggregate([
{"$group": {"_id": {"id": "$votes.id"}, "voteCount": {"$sum": 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 ]
}
}
}
}
])