按多个字段对集合数据进行分组 mongodb

Posted

技术标签:

【中文标题】按多个字段对集合数据进行分组 mongodb【英文标题】:group collection data by multiple fields mongodb 【发布时间】:2017-03-24 02:58:43 【问题描述】:

集合结构

Order = new Schema
    index:           type: Number, unique: true 
    number:         Date
    status:          type: String, enum: ['success', 'failure'] 
    created_at:      type: Date, default: Date.now 
    updated_at:      type: Date, default: Date.now 

我需要一个查询帮助,该查询返回一个对象数组,其中包含按日期分组的成功计数和失败计数数据。 前-

orders = 
              28-10-2016:
               success_count: 10, 
               failure_count: 10
              ,
              29-10-2016: 
               success_count: 10, 
               failure_count: 10
              
          

【问题讨论】:

请在此处发布您到目前为止所尝试的内容 @chridam 我希望他发布有问题的代码,而不是在 cmets 中,可能在我的评论中没有正确传达给他 :-) 【参考方案1】:

使用聚合框架,结果将与您的“所需”输出略有不同,因为您获得的不是散列键,而是带有 _id 键的对象数组,其值代表您按字段分组。例如,而不是


    "28-10-2016":
        "success_count": 10, 
        "failure_count": 10
    ,
    "29-10-2016": 
        "success_count": 10, 
        "failure_count": 10
    

你会有一个更好的结构,比如

[
    
        "_id": "28-10-2016",
        "success_count": 10, 
        "failure_count": 10
    ,
        "_id": "29-10-2016",
        "success_count": 10, 
        "failure_count": 10
    
]

实现上述结果需要在 $sum 累加器运算符中使用 $cond 运算符。 $cond 运算符将根据其第一个参数 (if) 计算逻辑条件,然后返回计算结果为 true (then) 的第二个参数或返回 false (else) 的第三个参数。这会将真/假逻辑转换为分别输入 $sum 的 1 和 0 数值:

"success_count": 
    "$sum": 
        "$cond": [  "$eq": [ "$status", "success" ] , 1, 0 ]
    

作为结果管道,需要运行聚合操作,该操作在 $group 管道的 _id 键表达式中使用 $dateToString 运算符:

Orders.aggregate([
    
        "$group": 
            "_id": 
                "$dateToString":  
                    "format": "%Y-%m-%d", 
                    "date": "$created_at" 
                
            ,
            "success_count": 
                "$sum": 
                    "$cond": [  "$eq": [ "$status", "success" ] , 1, 0 ]
                
            ,
            "failure_count": 
                "$sum": 
                    "$cond": [  "$eq": [ "$status", "failure" ] , 1, 0 ]
                
            
        
    
], function (err, orders)
    if (err) throw err;
    console.log(orders);
)

但是,有一种更灵活、性能更好的方法,它的执行速度比上述方法快得多,其中聚合结果的最有效数据结构遵循以下架构,例如:

orders = [
    
        "_id": "28-10-2016",
        "counts": [
             "status": "success", "count": 10 ,
             "status": "failure", "count": 10 
        ]
    ,
    
        "_id": "29-10-2016",
        "counts": [
             "status": "success", "count": 10 ,
             "status": "failure", "count": 10 
        ]
    
]

然后考虑运行如下替代管道

Orders.aggregate([
     
        "$group": 
            "_id":  
                "date":  
                    "$dateToString":  
                        "format": "%Y-%m-%d", 
                        "date": "$created_at" 
                    
                ,
                "status":  "$toLower": "$status" 
            ,
            "count":  "$sum": 1 
        
    ,
     
        "$group": 
            "_id": "$_id.date",
            "counts": 
                "$push": 
                    "status": "$_id.status",
                    "count": "$count"
                
            
        
    
], function (err, orders)
    if (err) throw err;
    console.log(orders);
)

【讨论】:

这正是我想要的。谢谢@chridam!

以上是关于按多个字段对集合数据进行分组 mongodb的主要内容,如果未能解决你的问题,请参考以下文章

使用多个选项按字段对 Drupal 视图进行分组 - 仅显示一个字段

尝试按对象分组作为键时,字段必须是累加器对象错误

集合List根据多个字段进行排序

mysql 数据库知识

在Kotlin中按多个字段对集合进行排序[重复]

如何按两个字段对数据进行分组?