Mongodb: подсчитывать значения массива с помощью mapreduce/aggregation

У меня есть документы со следующей структурой:

{
    "name" : "John",
    "items" : [
       {"key1" : "value1"},
       {"key1" : "value1"}
    ]
}

И построили простую функцию для подсчета количества «предметов».

var count = 0;
db.collection.find({},{items:1}).limit(10000).forEach(
    function (doc) {
        if(doc.items){
               count += doc.items.length;
        }
    }
)
print(count);

Но после ~ 1 миллиона пунктов моя функция ломается, Монго выходит. Я рассмотрел новую структуру агрегации, а также функции mapreduce, и я не уверен, что лучше всего использовать для простого подсчета.

Предложения приветствуются! Благодарю.

1
nl ja de
Вы получаете слишком много времени на курсор, если бы вы запускали команду say 10K, когда вы показываете время в цикле, каждый раз каждый раз должен открывать новый курсор, и вам не следует терпеть проблему с таймаутом.
добавлено автор Sammaye, источник

2 ответы

It becomes very easy when you use aggregation http://docs.mongodb.org/manual/core/aggregation-pipeline/

db.collection.aggregate(
     { $unwind : "$items" }, 
     { $group  : {_id:null, items_count : {$sum:1} }}
)

для возврата количества элементов для каждого документа,

{ $group  : {_id:"$_id", items_count : {$sum:1} }}
1
добавлено

Вы можете хранить длину doc.items как элемент документа. Этот метод вызывает избыточность диска, но быстрый и простой способ работы с большими коллекциями.

{
    "name" : "John",
    "itemsLength" : 2,
    "items" : [
       {"key1" : "value1"},
       {"key1" : "value1"}
    ]
}

Другим вариантом может быть использование mapreduce, но, я думаю, без осколки mapreduce будет медленным.

0
добавлено
Вы можете обновить предыдущие документы за один раз, чтобы все документы имели свойство itemLength. Когда все документы имеют itemLength, вы можете агрегировать их с помощью $ sum.
добавлено автор Muatik, источник
Длина «предметов» подсчитывается сейчас, но мне все еще нужно считать те предыдущие документы, которые еще не имеют ее.
добавлено автор L-R, источник
DBA - русскоговорящее сообщество
DBA - русскоговорящее сообщество
1 345 участник(ов)

Общаемся и обсуждаем темы, посвященные DBA, PostgreSQL, Redis, MongoDB, MySQL, neo4j, riak и т.д. См. также: @devops_ru, @kubernetes_ru, @docker_ru, @nodejs_ru Рекомендуем сразу отключить уведомления, чтобы пребывание здесь было полезным и комфортным.

MongoDB Russian
MongoDB Russian
1 086 участник(ов)

> db.stats() https://combot.org/chat/-1001035023078