在MongoDB中减去分组聚合值

3
我有一个集合,存储用户投票值,voteTypeID = 1代表赞成票,voteTypeID = 2代表反对票,并且还有一个与另一个集合相关联的loadoutID
我想按loadoutID分组,并获取所有赞成票并减去所有反对票,以获得差异。因此,如果一个载具有20个赞成票和2个反对票,我想得到loadoutID18
我承认我对聚合函数相当陌生,之前只用过它进行基本计数,但是它对我来说仍然不太清楚,非常感谢任何帮助。您能解释聚合的更多细节就更好了=)
这是我最近的失败尝试:
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
}
1个回答

7

聚合框架中的$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),所以条件也可以内联堆叠,这样就可以是正数、负数或没有任何东西。

第一次看到$cond运算符。因此,$eq: [voteTypeID, 1]是“if”语句,它返回1并且else链接到另一个$cond,如果votetypeID为2,则返回-1,或默认为零以不影响总和。非常感谢,我认为我不会这么快想出来=) - afreeland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接