2015-09-28 5 views
1

Я пытаюсь подсчитать различные значения в MongoDB, но я не получаю ожидаемых результатов.Подсчет отдельных значений в MongoDB

Вот пример данных:

{ 
     "_id" : ObjectId("55d354b0d5cec8aad571b8fe"), 
     "version" : "0.4", 
     "scan-time" : { 
       "start" : 1439913109, 
       "end" : 1439913136 
     }, 
     "services" : [ 
       { 
         "service-type" : "SV1", 
         "service-version" : "V1", 
         "location" : { 
           "ipv4-address" : "192.168.1.1", 
           "protocol" : "tcp" 
         }, 
         "classification-method" : "probed" 
       }, 
       { 
         "service-type" : "SV1", 
         "service-version" : "V2", 
         "location" : { 
           "ipv4-address" : "192.168.1.2", 
           "protocol" : "tcp" 
         }, 
         "classification-method" : "probed" 
       }, 
       { 
         "location" : { 
           "ipv4-address" : "192.168.1.3", 
           "protocol" : "tcp" 
         }, 
         "classification-method" : "probed", 
         "service-type" : "SV1", 
         "service-version" : "V3" 
       }, 
       { 
         "service-type" : "SV2", 
         "service-version" : null, 
         "location" : { 
           "ipv4-address" : "192.168.1.4", 
           "protocol" : "tcp" 
         }, 
         "classification-method" : "probed" 
       } 
     ] 
} 

Я могу перечислить все различные значения, используя этот запрос:

db.collection.distinct("services.service-type") 

Однако, я также нужен подсчет. Я попробовал это, но это не дает результаты, я хочу:

db.collection.aggregate(
    [ 
     { 
     $group : { 
      _id : "$services.service-type", 
      count: { $sum: 1 } 
     } 
     } 
    ] 
) 

Мне нужно увидеть это:

SV1: 3 
SV2: 1 

MongoDB версия:

> db.version() 
3.0.5 

Спасибо за любую помощь!

ответ

5

Чтобы использовать вложенный массив услуг в вашем отчетливым запросе, вам нужно разматывать $ услугу с $unwind

Следующего вывода будет опрашивать различные подсчетами:

db.collection.aggregate([  
    { $unwind: "$services" }, 
    { 
     $group : { 
     _id : { "services-service-type": "$services.service-type" }, 
     count: { $sum: 1 } 
     } 
    } 
]) 

Выход:

{ 
    "result" : [ 
     { 
      "_id" : { 
       "services-service-type" : "SV2" 
      }, 
      "count" : 1 
     }, 
     { 
      "_id" : { 
       "services-service-type" : "SV1" 
      }, 
      "count" : 3 
     } 
    ], 
    "ok" : 1 
} 
+0

Вы не должны '$ unwind' документа без '$ project'ing их. – styvane

+0

Большое спасибо, что я искал! – Tomas

1

Прежде всего вам необходимо указать $project ваши документы и вернуть массив из всех service-type, чтобы уменьшить размер документов, необходимых для обработки в конвейере, потому что $unwind дублирует каждый документ в коллекции. Для этого используется оператор $map. Тогда вы можете $unwind обратный массив и, наконец, в вашей группе проекте вы используете $sum аккумулятор для возврата счетчика отчетливого service-type

db.collection.aggregate([ 
    { "$project": { 
     "services": { 
      "$map": { 
       "input": "$services", 
       "as": "s", 
       "in": "$$s.service-type" 
      } 
     } 
    }}, 
    { "$unwind": "$services" }, 
    { "$group": { 
     "_id": "$services", 
     "count": { "$sum": 1 } 
    }} 
]) 

который возвращает:

{ "_id" : "SV2", "count" : 1 } 
{ "_id" : "SV1", "count" : 3 } 
+0

Большое спасибо, вот что я искал! – Tomas

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