2013-08-01 3 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», «статус »и счет комбинации. Я хочу, чтобы получить результат, который выглядит следующим образом:

[{ 
    "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 
} 

Однако Я не вижу, как я могу $ проектировать каждый статус («ОК» или «ERR») на правильный вывод, чтобы они были полями в записи, идентифицированной «потоком сообщений». Есть идеи?

ответ

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, потому что это поле является вашей основной оси. Затем, чтобы подсчитать количество erros и успехов, я использую оператор $sum в сочетании с $cond и $eq. Он просто сравнивает, если status является ERR или ОК и правильно суммируется.

+0

Отлично. Спасибо Мигелю. Погрузившись в рамки Монгосской агрегации. Цените помощь! – Damo

+0

Что делать, если у меня не было меток «ошибок» и «успехов», и вместо этого хотелось, чтобы метка была статусом, с которым она группировалась, например. «ERR», «OK» или другой статус в коллекции? – Damo

Смежные вопросы