2014-02-21 180 views
5

我有以下MongoDB查询按日期和结果分组,并给出一个计数。如果数据在当天不存在,我希望查询也返回特定日期和结果的计数为0。如果没有结果,MongoDB聚合返回计数为0

例如,我有以下结果状态:成功和失败。如果21号没有失败我希望计数返回0结果:

{ 
    "_id" : { 
      "month" : 1, 
      "day" : 21, 
      "year" : 2014, 
      "buildResult" : "FAILURE" 
    }, 
    "count" : 0 
} 

我已经做了一个关系型数据库和日历表类似的东西,但我不知道如何处理这与MongoDB。这是可能的或者我应该在运行查询后以编程方式执行某些操作?

这里是在数据库中的文档(简体)的例子:

{ 
      "_id" : ObjectId("52deab2fe4b0a491abb54108"), 
      "type" : "build", 
      "time" : ISODate("2014-01-21T17:15:27.471Z"), 
      "data" : { 
        "buildNumber" : 43, 
        "buildDuration" : 997308, 
        "buildResult" : "SUCCESS" 
      } 
    } 

这里是我当前的查询:

db.builds.aggregate([ 
    { $match: { "data.buildResult" : { $ne : null} }}, 
    { $group: { 
     _id: { 
      month: { $month: "$time" }, 
      day: { $dayOfMonth: "$time" }, 
      year: { $year: "$time" }, 
      buildResult: "$data.buildResult", 
     }, 
     count: { $sum: 1} 
    } }, 

    { $sort: { "_id.year": 1, "_id.month": 1, "_id.day": 1} } 
]) 
+1

我不相信在任何可用范围之外建立范围仍然存在,即通常会存在的日期是1/2/2013,但在这种情况下并不是这样,所以您希望在那里有0。 – Sammaye

+0

是否有可能添加类似日历集合的东西?我用关系数据库创建了一个日历表来做同样的事情。基本上将日历表与数据表结合起来以查找缺失的记录。 – JamesE

+0

您可以添加一个映射器并将聚合映射到该日历表,这是一个合法的方法 – Sammaye

回答

0

如果我理解正确,你想要什么,你可以尝试这样的:

db.builds.aggregate([ 
    { $project: 
     { 
      time: 1, 
      projectedData: { $ifNull: ['$data.buildResult', 'none'] } 
     } 
    }, 

    { $group: { 
     _id: { 
      month: { $month: "$time" }, 
      day: { $dayOfMonth: "$time" }, 
      year: { $year: "$time" }, 
      buildResult: "$projectedData" 
     }, 
     count: { $sum: { $cond: [ { $eq: [ "$projectedData", "none" ] }, 0, 1 ] } } 
    } }, 

    { $sort: { "_id.year": 1, "_id.month": 1, "_id.day": 1 } } 
]) 

更新:
您希望从输出中获得更多输入的文档,但只有与数组一起工作的unwind运算符才有可能,但您没有任何数组,因为我知道无法在您的案例中获取更多文档。所以你应该在查询结果后添加一些逻辑来为现有日期创建新数据,对于另一种类型的buildResult,使用0计数...

+1

谢谢,但不完全(我会尽量让问题更清楚)。我真正想要的是,如果在特定日期没有特定结果的记录,则计数为0。因此,如果1月21日没有失败的结果,计数将显示为0。 – JamesE