在MongoDB中减去组聚合值

时间:2014-12-14 19:47:12

标签: mongodb mongodb-query aggregation-framework

我有一个集合,用于存储用户投票值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']}
        }
    }
])

1 个答案:

答案 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),因此条件也可以在线堆叠。无论是积极的还是消极的,或者没有。