我有一个集合,用于存储用户投票值voteTypeID = 1
以进行投票,voteTypeID = 2
表示向下投票,loadoutID
表示与其他集合绑定。
我希望按loadoutID
进行分组并采取所有向上投票并减去所有向下投票,以获得差异。因此,如果装载 20 向上投票且 2 向下投票,我希望返回 18 以及{{1 }}
我承认我对聚合函数相当新,并且之前只使用它进行基本计数而且它还没有为我点击过,任何帮助都非常感谢。你越能解释聚合越好=)
这是我最近的失败尝试
loadoutID
JSON数据
LoadoutVotes.aggregate([
{
$group: {
_id: '$loadoutID',
up: { $sum: { voteTypeID: 1}},
down: { $sum: { voteTypeID: 2 }}
}
},
{
$project: {
_id: '$loadoutID',
count: {$subtract: ['$up', '$down']}
}
}
])
答案 0 :(得分:6)
聚合框架中的$sum
运算符接受一个参数,该参数是应用于分组的数值。通常,当您想要计算出现次数时,您希望它是文档中字段的值或类似1
的值。
您要做的是“有条件地”评估字段值,为此有$cond
运算符。这将根据您的voteTypeID
字段确定要应用的值。所以你可以这样写:
LoaodoutVotes.aggregate([
{ "$group": {
"_id": "$loadoutID",
"up": {
"$sum": {
"$cond": [
{ "$eq": [ "$voteTypeID", 1 ] },
1,
0
]
}
},
"down": {
"$sum": {
"$cond": [
{ "$eq": [ "$voteTypeID", 2 ] },
1,
0
]
}
},
}},
{ "$project": {
"loadoutID": "$_id",
"count": { "$subtract": [ "$up", "$down" ] }
}}
])
或者甚至更高效,因为你可以在线“签署”这些值:
LoaodoutVotes.aggregate([
{ "$group": {
"_id": "$loadoutID",
"count": {
"$sum": {
"$cond": [
{ "$eq": [ "$voteTypeID", 1 ] },
1,
{ "$cond": [
{ "$eq": [ "$voteTypeID", 2 ] },
-1,
0
]}
]
}
}
}}
])
因为 $group
现在只是管道中的一次传递,因此效率更高。由于 $cond
是三元运算符(if-then-else),因此条件也可以在线堆叠。无论是积极的还是消极的,或者没有。