2016-05-27 3 views
1

Моя коллекция выглядит следующим образом:MongoDB подсчитать количество документов для каждой категории

{ 
    "_id":ObjectId("5744b6cd9c408cea15964d18"), 
    "uuid":"bbde4bba-062b-4024-9bb0-8b12656afa7e", 
    "version":1, 
    "categories":["sport"] 
    }, 
    { 
    "_id":ObjectId("5745d2bab047379469e10e27"), 
    "uuid":"bbde4bba-062b-4024-9bb0-8b12656afa7e", 
    "version":2, 
    "categories":["sport", "shopping"] 
    }, 
    { 
    "_id":ObjectId("5744b6359c408cea15964d15"), 
    "uuid":"561c3705-ba6d-432b-98fb-254483fcbefa", 
    "version":1, 
    "categories":["politics"] 
    } 

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

db.collection.aggregate( 
{$unwind: '$categories'}, 
{$group: {_id: '$categories', count: {$sum: 1}} } 
) 

Результат:

{ "_id" : "sport", "count" : 2 } 
    { "_id" : "shopping", "count" : 1 } 
    { "_id" : "politics", "count" : 1 } 

Теперь я хочу, чтобы подсчитать количество документов для каждой категории, но где версия документа является последней версией.

Здесь я застреваю.

+0

Какая последняя версия? 1 или 2? или даже варьируется между документами? Тот же UUID? –

+0

Да, тот же uuid. Последняя версия - 2. – Martin

ответ

0

Это некрасиво, но я думаю, что это дает вам то, что вы после:

db.collection.aggregate( 
{ $unwind : "$categories" }, 
{ $group : 
    { "_id" : { "uuid" : "$uuid" }, 
    "doc" : { $push : { "version" : "$version", "category" : "$categories" } }, 
    "maxVersion" : { $max : "$version" } 
    } 
}, 
{ $unwind : "$doc" }, 
{ $project : { "_id" : 0, "uuid" : "$id.uuid", "category" : "$doc.category", "isCurrentVersion" : { $eq : [ "$doc.version", "$maxVersion" ] } } }, 
{ $match : { "isCurrentVersion" : true }}, 
{ $group : { "_id" : "$category", "count" : { $sum : 1 } } } 
) 
0

Вы можете сделать это первым группируя Денормализованные документов (с шагом оператора $unwind) двумя ключами, то есть categories и version полей. Это необходимо для предыдущего этапа перехода, который заказывает сгруппированные документы и их накопленные подсчеты по версиям (desc) и категориям (asc) соответственно, используя оператор $sort.

Другая группировка будет требоваться, чтобы получить верхние документы в каждой группе categories после заказа с помощью оператора в $first. Ниже показано это

db.collection.aggregate( 
    { "$unwind": "$categories" }, 
    { 
     "$group": { 
      "_id": { 
       'categories': '$categories', 
       'version': '$version'    
      }, 
      "count": { "$sum": 1 } 
     } 
    }, 
    { "$sort": { "_id.version": -1, "_id.categories": 1 } }, 
    { 
     "$group": { 
      "_id": "$_id.categories", 
      "count": { "$first": "$count" }, 
      "version": { "$first": "$_id.version" }   
     } 
    } 
) 

Пример вывода

{ "_id" : "shopping", "count" : 1, "version" : 2 } 
{ "_id" : "sport", "count" : 1, "version" : 2 } 
{ "_id" : "politics", "count" : 1, "version" : 1 } 
+0

Если документ изменен, например, с uuid: «bbde4bba-062b-4024-9bb0-8b12656afa7e», так что в версии 2 категории: [«shopping»] этот запрос выведет { «_id»: «спорт», «счет»: 1, «версия»: 1}. – Martin

+0

Выполнение конвейера агрегации еще раз с этими изменениями даст вам результат '{" _id ":" shopping "," count ": 1," version ": 2} {" _id ":" policy "," count " : 1, "version": 1} {"_id": "sport", "count": 1, "version": 1} 'Есть ли что-то, что мне не хватает в вопросе, который делает недействительным ответ? – chridam

+0

Вывод в этом случае должен быть {"_id": "shopping", "count": 1, "version": 2} {"_id": "policy", "count": 1, "version": 1 }, потому что последняя версия этого документа больше не содержит категорию «спорт». – Martin

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