2013-08-01 44 views
0

我有這樣一組數據:

> db.esbtrans.find().limit(2).pretty() 
{ 
    "_id" : ObjectId("51fa56a509d013ddbd06f513"), 
    "messageflow" : "TEST", 
    "correlid" : "2b2bdc4f-24bc-412a-8438-9a7e0c256b38", 
    "start" : ISODate("2013-08-01T12:37:57.452Z"), 
    "finish" : ISODate("2013-08-01T12:38:17.452Z"), 
    "response" : NumberLong(20000), 
    "status" : "OK" 
} 
{ 
    "_id" : ObjectId("51fa56a509d013ddbd06f514"), 
    "messageflow" : "TEST", 
    "correlid" : "0565d123-3570-4ce9-83d7-86e50aad48c5", 
    "start" : ISODate("2013-08-01T12:37:57.452Z"), 
    "finish" : ISODate("2013-08-01T12:38:44.452Z"), 
    "response" : NumberLong(47000), 
    "status" : "ERR" 
} 
{ 
    "_id" : ObjectId("51fa56a509d013ddbd06f515"), 
    "messageflow" : "TEST2", 
    "correlid" : "d14c447a-eb4c-4a00-85fd-009955798386", 
    "start" : ISODate("2013-08-01T12:37:57.452Z"), 
    "finish" : ISODate("2013-08-01T12:38:57.452Z"), 
    "response" : NumberLong(60000), 
    "status" : "OK" 
} 
{ 
    "_id" : ObjectId("51fa56a509d013ddbd06f516"), 
    "messageflow" : "TEST2", 
    "correlid" : "3b7902ce-a8bb-496a-a67f-23b562554c16", 
    "start" : ISODate("2013-08-01T12:37:57.452Z"), 
    "finish" : ISODate("2013-08-01T12:38:50.452Z"), 
    "response" : NumberLong(53000), 
    "status" : "ERR" 
} 

以下是這將是數以萬計的類似記錄,關鍵屬性是「消息流」兩個元素,「狀態「和組合計數。我想要得到的結果,看起來像這樣:

[{ 
    "messageflow: "TEST", 
    "errors": 1, 
    "successes": 1 
},{ 
    "messageflow: "TEST2", 
    "errors": 1, 
    "successes": 1 
}] 

我已經得到儘可能的聚集是這樣的:

> db.esbtrans.aggregate(
    {"$group": 
     {_id: {messageflow: "$messageflow", status: "$status"}, 
     resptot: {$sum: "$response"}, 
     count: {$sum: 1}}}, 
    {"$project": 
     {flow: "$_id.messageflow", 
     status: "$_id.status", 
     count: "$count", 
     _id: 0}}) 

將會產生類似的結果:

{ 
    "result" : [ 
     { 
      "count" : 240, 
      "flow" : "TEST2", 
      "status" : "ERR" 
     }, 
     { 
      "count" : 267, 
      "flow" : "TEST", 
      "status" : "ERR" 
     }, 
     { 
      "count" : 244, 
      "flow" : "TEST", 
      "status" : "OK" 
     }, 
     { 
      "count" : 249, 
      "flow" : "TEST2", 
      "status" : "OK" 
     } 
    ], 
    "ok" : 1 
} 

然而我無法看到如何將每個狀態(「OK」或「ERR」)投影到正確的輸出上,以便它們是由「messageflow」標識的記錄中的字段。有任何想法嗎?

回答

3

達摩,你必須記住的一件事是,當你想按值分組時,你可能不得不使用$ cond操作符。

db.esbtrans.aggregate({ 
    $group : { 
     _id : "$messageflow", 
     errors : { $sum : { $cond : [ { $eq : ["$status", "ERR"] } ,1,0] } }, 
     successes : { $sum : { $cond : [ { $eq : ["$status", "OK"] } ,1,0] } }, 
    } 
}) 

解釋: I組由messageflow,因爲這個領域是你的基本軸。然後爲了計算錯誤和成功的次數,我使用$sum算子結合$cond$eq。它只是比較status是ERR還是OK並且正確相加。

+0

太好了。謝謝米格爾。讓我的頭腦圍繞着Mongo Aggregation框架。感謝幫助! – Damo

+0

如果我沒有「錯誤」和「成功」的標籤,而是希望標籤成爲分組的狀態,例如。 「錯誤」,「確定」或集合中的其他狀態? – Damo