首页 > 解决方案 > 按多个字段分组并在两个条件下自定义总和

问题描述

我想用两个条件对行进行分组。第一个获取total(现在可以使用),第二个获取unread消息。我无法想象该怎么做。插入是:

db.messages.insert({'source_user': 'test1', 'destination_user': 'test2', 'is_read': true})
db.messages.insert({'source_user': 'test1', 'destination_user': 'test2', 'is_read': false})
db.messages.insert({'source_user': 'test1', 'destination_user': 'test3', 'is_read': true})

我的代码:

db.messages.aggregate([
    {'$match': {'source_user': user}},
    {'$group': {
        '_id': {
            'source_user': '$source_user',
            'destination_user': '$destination_user',
            'is_read': '$is_read'
        },
        'total': {'$sum': 1}}
    },
    {'$project': {
        'source_user': '$_id.source_user',
        'destination_user': '$_id.destination_user',
        #'unread': {'$sum': {'$_id.is_read': False}},
        'total': '$total',
        '_id': 0
    }}
    ])

结果我想得到:

[{
    'source_user': 'test1',
    'destination_user': 'test2',
    'unread': 1,
    'total': 2
  }, {
    'source_user': 'test1',
    'destination_user': 'test3',
    'unread': 0,
    'total': 1
 }
]

我应该添加一个新组还是可以$is_read在同一组中使用标志?

谢谢!

标签: mongodbmongodb-queryaggregation-framework

解决方案


您可以按照与总数相同的方式计算未读消息,但您需要应用$cond仅添加0消息和1其他消息:

db.messages.aggregate([
    {'$match': {'source_user': user}},
    {'$group': {
        '_id': {
            'source_user': '$source_user',
            'destination_user': '$destination_user'
        },
        'total': {'$sum': 1},
        'unread': {'$sum': { '$cond': [ '$is_read', 0, 1 ] }}
        }
    },
    {'$project': {
        'source_user': '$_id.source_user',
        'destination_user': '$_id.destination_user',
        'total': 1,
        'unread': 1,
        '_id': 0
    }}
])

MongoDB游乐场


推荐阅读