2013-10-10 2 views
0

Я пытаюсь собрать некоторую информацию, поступающую с разных устройств. Учитывая набор идентификаторов устройств, я хотел бы подсчитать количество значений времени. Бит, с которым я борюсь, - это только желание работать с последним отчетом каждого устройства.Mongo aggregations с множественным совпадением или объединением

Например, 4 устройства хранят сотни тысяч отчетов в коллекции отчетов. В отчетах сообщается, было ли событие networkDown или нет (логическое). Я хочу подсчитать количество раз, когда networkdown является истинным или ложным в последних отчетах 4 устройства.

Я использую MongoDB 2.4.4

отчет выглядит примерно так:

{ 
    "_id":ObjectId("52571500fa1fc70437000001"), 
    "device_id" : ObjectId("51f14f9f9809c4404f00000a"), 
    "payload":{ 
    "name":"Status", 
    "properties":{ 
     "property":{ 
     "deviceIdentifier":"My Device", 
     "networkDown":"false" 
     } 
    } 
    }, 
    "updated_at":ISODate("2013-10-10T20:58:40.674Z"), 
    "created_at":ISODate("2013-10-10T20:58:40.674Z") 
} 

группы я могу сделать на все записи для всех 4-х устройств. Скажем,

db.report.aggregate(
    [ 
    { $match: { device_id: 
     { 
      $in:   
      [ 
      ObjectId("51f14f9f9809c4404f00000a"), 
      ObjectId("523ab68a9809c4e490000059"), 
      ObjectId("522f37b89809c4e8cf000033"), 
      ObjectId("522f38019809c4ae070000d3")   
      ] 
     } 
     } 
    },  
    { $group: { _id: "$payload.properties.property.networkDown", total: { $sum: 1 } } }      
    ]) 


{ 
    "result" : [ 
     { 
      "_id" : "true", 
      "total" : 2 
     }, 
     { 
      "_id" : "false", 
      "total" : 278539 
     } 
    ], 
    "ok" : 1 
} 

Но как я могу ограничить запрос только работой над последним отчетом для каждого устройства?

Спасибо, что посмотрели!

ответ

0

Вы будете иметь первый сорт на основе {updated_at:1} группы .Затем по DEVICE_ID и использовать оператор в $ последний взять только последний networkDown поле, так как документы сортируются. Затем выполните другую группу в свойстве networkDown. Я знаю его немного сложнее, но вот вопрос:

db.reports.aggregate(
[ 
{ $match: { device_id: 
     { 
      $in:   
      [ 
      ObjectId("51f14f9f9809c4404f00000a"), 
      ObjectId("523ab68a9809c4e490000059"), 
      ObjectId("522f37b89809c4e8cf000033"), 
      ObjectId("522f38019809c4ae070000d3")   
      ] 
     } 
     } 
    }, 
    {$sort:{updated_at:1}}, 
    {$group: 
     {_id:"$device_id", 
     networkDown:{$last:"$payload.properties.property.networkDown"} 
     } 
    }, 
    {$group:{_id:"$networkDown",count:{$sum:1}}} 
]) 

Я не пробовал это правильно, но это должно work.Let мне знать, в случае каких-либо propblem

+0

Спасибо за глядя на это! Я получаю результат, которого я ожидал бы. Умная идея группировать по идентификатору устройства и принимать $ last. К сожалению, время запроса слишком велико, чтобы соответствовать требованиям, поэтому я думаю, что мне придется использовать что-то другое, кроме агрегации. Я хочу, чтобы агрегатный конвейер имел способ комбинировать наборы, чтобы я мог $ ограничивать 1 для каждого из устройств до группировки. Благодаря! – Linkadvitch

+0

Сортировка в порядке убывания и использование $ first должно помочь немного увеличить производительность. Вы можете использовать индекс в поле updated_at для дальнейшего улучшения. – Ishaan

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