2013-02-20 3 views
2

Имея mongodb с объемом около 100 ГБ данных и для каждого поля в выражении $ match, у меня есть индекс (индекс одного поля).

Теперь я попробовал aggregate() и написал $ project как первую часть в конвейере, $ match за этим.

Агрегация работает и возвращает правильные результаты, но это занимает несколько часов! Это действительно обрабатывает только отфильтрованные данные ($ match) или собирает mongo во весь диапазон данных и затем фильтрует?

В моем тестовом случае фильтры соответствия $ соответствуют 150 МБ (вместо полного размера данных 100 ГБ).

Случайно я изменил порядок и написал $ match перед $ project в определении конвейера. Таким образом, это было сделано в течение нескольких секунд.

Когда mongodb обычно сокращает входные данные и также имеет дело с индексом для полей в $ match?

ответ

2

Как вы заметили, порядок операторов трубопроводов очень важен, особенно при работе с большой коллекцией. Если сделано неправильно, вы можете исчерпать память, не говоря уже о длительном процессе. Как было отмечено in the docs:

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

$match 
$sort 
$limit 
$skip. 

Так что, пока $match приходит Спереди индекс может использоваться. Также отмечено in the docs

В MongoDB потоки агрегации трубопроводов MongoDB документы от одного оператора трубопровода к другому, чтобы обработать документы. Трубопроводы могут быть повторены в трубе.

Это означает, что ваш $project видит только часть всей коллекции, если она предшествует $match.

+0

Я нахожу общую структуру настолько поразительной. Возможность упорядочить операторов любым способом, который вам нравится, действительно открывает миры возможностей. Этот ответ помог мне понять, что я могу '$ match' после' $ project', таким образом, я мог бы фильтровать поля после '$ project'. – Rohmer