【问题标题】:Subtract group aggregate values in MongoDB减去 MongoDB 中的组聚合值
【发布时间】:2015-02-12 21:58:34
【问题描述】:

我有一个集合,其中存储用户投票值voteTypeID = 1 表示赞成票,voteTypeID = 2 表示反对票,还有一个 loadoutID 与另一个集合相关联。

我想按loadoutID 分组并接受所有赞成票并减去所有反对票,以获得差异。因此,如果加载有 20 个赞成票和 2 个反对票,我想找回 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
}

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案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 是三元运算符( if-then-else ),因此条件也可以内联堆叠。所以要么是正面的,要么是负面的,要么什么都没有。

    【讨论】:

    • 第一次看到 $cond 运算符。所以 $eq: [voteTypeID, 1] 是 'if' 语句,它返回一个 1 并且 else 链接到另一个 $cond,如果 votetypeID 为 2 或默认为零不影响总和,它将返回一个 -1。欣赏这一点,我想我不会这么快就想出这个=)
    猜你喜欢
    • 1970-01-01
    • 2018-08-17
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 2020-11-09
    • 1970-01-01
    相关资源
    最近更新 更多