2014-02-21 256 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