按多个字段分组并格式化结果

时间:2018-03-14 03:45:40

标签: mongodb aggregation-framework

我正在尝试按线束和日期对所有记录进行分组。然后显示该日期的总持续时间。

文档结构

const testResultsSchema = new Schema({
    duration: Number,
    status: Boolean,
    start_date: Date,
    end_date: Date,
    harness: String
});

查询我正在运行:db.ecommresults.aggregate(

[
  { $project :
     {
       _id: 0,
       harness: 1,
       duration: 1,
       end_date: 1
     }
  },
  { $group :
     {
       _id: { harness: "$harness", testDay: { $dateToString: { format: "%Y-%m-%d", date: "$end_date" } } },
        "total_time" : { $sum: "$duration" }
     }
  }
]).pretty();

我收到以下输出

{
        "_id" : {
                "harness" : "api",
                "testDay" : "2018-03-11"
        },
        "total_time" : 120
}
{
        "_id" : {
                "harness" : "api",
                "testDay" : "2018-03-10"
        },
        "total_time" : 120
}
{
        "_id" : {
                "harness" : "api",
                "testDay" : "2018-03-12"
        },
        "total_time" : 33
}
{
        "_id" : {
                "harness" : "selenium",
                "testDay" : "2018-03-11"
        },
        "total_time" : 306
}

输出格式不是我的目标,我想要

 "api" {
      { "testDay: "2018-03-11", "total_time": 306 }
      { "testDay: "2018-03-12", "total_time": 542 }
     },
     "selenium" {
      {"testDay: "2018-03-11", "total_time": 645 },
      {"testDay: "2018-03-16", "total_time": 444 }
     }
    }

我正在使用node,express,mongoose,然后在react应用程序中使用响应。我希望发送格式化的数据,以方便客户使用。

我是mongo的新手(实际上我正试图使用​​的所有堆栈)。

2 个答案:

答案 0 :(得分:1)

您可以使用以下代码在3.4中获取所需的格式。

添加额外$group以通过线束获取值,然后$replaceRoot添加$arrayToObject以将单值数组转换为命名键值对。

[
  {"$group":{
    "_id":{"harness":"$harness","testDay":"$testDay"},
    "total_time":{"$sum":"$duration"}
  }},
  {"$group":{
    "_id":"$_id.harness",
    "v":{"$push":{"testDay":"$_id.testDay","total_time":"$total_time"}}
  }},
 {"$replaceRoot":{"newRoot":{
  "$let":{
    "vars":{"array":[{"k":"$_id", "v":"$v"}]},
    "in":{"$arrayToObject":"$$array"}}
 }}}
]

答案 1 :(得分:0)

Mongodb目前不支持动态字段,因此您需要将其括在命名字段中。我添加了片段,看看它是否适合您。

String msg = "This is a test";
int key = 88;
StringBuilder sb = new StringBuilder();
for(int i=0; i<msg.length(); i++)
    sb.append((char)(msg.charAt(i)^key));
System.out.println(sb.toString());

将按此输出

   db.getCollection('groupby').aggregate([
       { "$sort": { "end_date": 1 } },
      {"$group":{
        "_id":{"harness":"$harness","testDay":"$end_date"},
        "total_time":{"$sum":"$duration"}
      }},
      {"$group":{
        "_id":"$_id.harness",
        "v":{"$push":{"testDay":"$_id.testDay","total_time":"$total_time"}}
      }},
      {"$group": {
          "_id": "",
          "data": {"$push": "$$ROOT"}
      }
      }
    ])

希望它有所帮助。