我有一个集合,它存储一个用户投票值voteTypeID = 1
用于向上投票,一个voteTypeID = 2
用于向下投票,还有一个loadoutID
用于与另一个集合绑定。
我想按loadoutID
分组,把所有的上下票数减去,得到差额。因此,如果一个loadout有20个上下投票,我想得到18个以及loadoutID
。
我承认我对聚合函数还不太熟悉,以前只使用它进行基本计数,但它还没有为我点击,任何帮助都非常感谢。你越能解释这个总数,就越好=)
这是我最近一次失败的尝试
LoadoutVotes.aggregate([
{
$group: {
_id: '$loadoutID',
up: { $sum: { voteTypeID: 1}},
down: { $sum: { voteTypeID: 2 }}
}
},
{
$project: {
_id: '$loadoutID',
count: {$subtract: ['$up', '$down']}
}
}
])
JSON数据
{
loadoutID: 'ObjectID-String',
voteTypeID: 1
}
最佳答案
聚合框架中的$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
是三元运算符(如果是,则为else),因此条件也可以按行堆叠。所以要么是积极的要么是消极的要么什么都没有。