我有一个集合,它存储一个用户投票值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),因此条件也可以按行堆叠。所以要么是积极的要么是消极的要么什么都没有。

07-28 09:52