Это некоторая информация об использовании $group
этапа агрегации, если он использует индексы, его ограничения и что можно попытаться преодолеть.
1. Этап $ group не использует индекс : Mongodb Агрегация: использует ли $ group индекс?
2. $ group Оператор и память :
Этап $group
имеет ограничение в 100 мегабайт оперативной памяти. По умолчанию, если уровень превышает этот предел, $group
возвращает ошибку. Чтобы разрешить обработку больших наборов данных, установите для параметра allowDiskUse
значение true. Этот флаг позволяет операциям $ group записывать во временные файлы.
См. Документы MongoDb для $ group Оператор и память
3. Пример с использованием $ group и Count :
Коллекция называется cities
:
{ "_id" : 1, "city" : "Bangalore", "country" : "India" }
{ "_id" : 2, "city" : "New York", "country" : "United States" }
{ "_id" : 3, "city" : "Canberra", "country" : "Australia" }
{ "_id" : 4, "city" : "Hyderabad", "country" : "India" }
{ "_id" : 5, "city" : "Chicago", "country" : "United States" }
{ "_id" : 6, "city" : "Amritsar", "country" : "India" }
{ "_id" : 7, "city" : "Ankara", "country" : "Turkey" }
{ "_id" : 8, "city" : "Sydney", "country" : "Australia" }
{ "_id" : 9, "city" : "Srinagar", "country" : "India" }
{ "_id" : 10, "city" : "San Francisco", "country" : "United States" }
Запрос коллекция для подсчета городов в каждой стране:
db.cities.aggregate( [
{ $group: { _id: "$country", cityCount: { $sum: 1 } } },
{ $project: { country: "$_id", _id: 0, cityCount: 1 } }
] )
Результат :
{ "cityCount" : 3, "country" : "United States" }
{ "cityCount" : 1, "country" : "Turkey" }
{ "cityCount" : 2, "country" : "Australia" }
{ "cityCount" : 4, "country" : "India" }
4. Использование параметра allowDiskUse :
db.cities.aggregate( [
{ $group: { _id: "$country", cityCount: { $sum: 1 } } },
{ $project: { country: "$_id", _id: 0, cityCount: 1 } }
], { allowDiskUse : true } )
Обратите внимание, что в этом случае нет никакой разницы в производительности или выводе запроса. Это показывает только использование.
5. Некоторые варианты, чтобы попробовать (предложения) :
Вы можете попробовать несколько вещей, чтобы получить некоторый результат (только для ознакомительных целей):
- Использовать
$limit
stage и ограничитьколичество обработанных документов и посмотреть, каков результат. Например, вы можете попробовать { $limit: 1000 }
. Обратите внимание, что этот этап должен предшествовать этапу $group
. - Вы также можете использовать этапы
$match
, $project
перед этапом $group
для управления shape и size входа. Это может вернуть результат (вместо ошибки).
[РЕДАКТИРОВАТЬ ДОБАВИТЬ] Примечания о различных иКоличество:
Использование той же коллекции cities
- чтобы получить уникальные страны и их количество, вы можете попробовать использовать стадию агрегирования $count
вместе с $group
, как в следующих двух запросах.
Distinct:
db.cities.aggregate( [
{ $match: { country: { $exists: true } } },
{ $group: { _id: "$country" } },
{ $project: { country: "$_id", _id: 0 } }
] )
Результат:
{ "country" : "United States" }
{ "country" : "Turkey" }
{ "country" : "India" }
{ "country" : "Australia" }
Чтобы получить вышеуказанный результат в виде одного документа с массивом уникальных значений, используйте оператор $addToSet
:
db.cities.aggregate( [
{ $match: { country: { $exists: true } } },
{ $group: { _id: null, uniqueCountries: { $addToSet: "$country" } } },
{ $project: { _id: 0 } },
] )
Результат: { "uniqueCountries" : [ "United States", "Turkey", "India", "Australia" ] }
Количество:
db.cities.aggregate( [
{ $match: { country: { $exists: true } } },
{ $group: { _id: "$country" } },
{ $project: { country: "$_id", _id: 0 } },
{ $count: "uniqueCountryCount" }
] )
Результат: { "uniqueCountryCount" : 4 }
В вышеупомянутых запросах этап $match
используется для фильтрации любых документов с несуществующим или нулевым полем country
. Этап $project
изменяет форму документа (ов).
Язык запросов MongoDB:
Обратите внимание, что два запроса получают схожие результаты при использовании запроса MongoDBкоманды language : db.collection.distinct("country")
и db.cities.distinct("country").length
(обратите внимание, distinct
возвращает массив).