Агрегация в MongoDB
В MongoDB агрегация в основном используется для обработки данных (например, вычисления средних значений, сумм и т. д.) и возврата вычисленных результатов.
несколько похоже наSQLв SQL-инструкцииcount(*)。
метод aggregate()
Метод агрегации в MongoDB использует aggregate().
Синтаксис
Базовый формат синтаксиса метода aggregate() выглядит следующим образом:
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
Пример
Данные в коллекции выглядят следующим образом:
{
_id: ObjectId(7df78ad8902c)
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by_user: 'example.com',
url: 'http://www.example.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
},
{
_id: ObjectId(7df78ad8902d)
title: 'NoSQL Overview',
description: 'No sql database is very fast',
by_user: 'example.com',
url: 'http://www.example.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 10
},
{
_id: ObjectId(7df78ad8902e)
title: 'Neo4j Overview',
description: 'Neo4j is no sql database',
by_user: 'Neo4j',
url: 'http://www.neo4j.com',
tags: ['neo4j', 'database', 'NoSQL'],
likes: 750
},
Теперь давайте используем указанную выше коллекцию, чтобы вычислить количество статей, написанных каждым автором. Результат использования aggregate() выглядит следующим образом:
> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{
"result" : [
{
"_id" : "example.com",
"num_tutorial" : 2
},
{
"_id" : "Neo4j",
"num_tutorial" : 1
}
],
"ok" : 1
}
>
Приведённый выше пример аналогичен SQL-инструкции:
select by_user, count(*) from mycol group by by_user
В приведённом выше примере мы группируем данные по полю by_user и вычисляем сумму одинаковых значений в поле by_user.
В следующей таблице показаны некоторые выражения агрегации:
| Выражение | Описание | Пример |
|---|---|---|
| $sum | Вычисляет сумму. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) |
| $avg | Вычисляет среднее значение | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) |
| $min | Получает минимальное значение, соответствующее всем документам в коллекции. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) |
| $max | Получает максимальное значение, соответствующее всем документам в коллекции. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) |
| $push | Добавляет значения в массив без проверки на дубликаты. | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) |
| $addToSet | Добавляет значения в массив, проверяя на дубликаты; если такое же значение уже есть в массиве, оно не добавляется. | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
| $first | Получает данные первого документа в соответствии с сортировкой исходных документов. | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
| $last | Получает данные последнего документа в соответствии с сортировкой исходных документов. | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
Концепция конвейера
В Unix и Linux конвейеры обычно используются для передачи вывода текущей команды в качестве аргумента для следующей команды.
Конвейер агрегации MongoDB обрабатывает документы MongoDB на одной стадии конвейера, а затем передаёт результаты на следующую стадию конвейера. Операции конвейера могут повторяться.
Выражение: обрабатывает входные документы и выводит результаты. Выражения не имеют состояния и могут использоваться только для вычисления документов в текущем конвейере агрегации; они не могут обрабатывать другие документы.
Здесь мы представим несколько часто используемых операций во фреймворке агрегации:
- $project: изменяет структуру входного документа. Его можно использовать для переименования, добавления или удаления полей, а также для создания вычисляемых результатов и вложенных документов.
- $match: используется для фильтрации данных и вывода только тех документов, которые соответствуют условиям. $match использует стандартные операции запросов MongoDB.
- $limit: используется для ограничения количества документов, возвращаемых конвейером агрегации MongoDB.
- $skip: пропускает указанное количество документов в конвейере агрегации и возвращает оставшиеся документы.
- $unwind: разбивает поле типа массив в документе на несколько документов, каждый из которых содержит одно значение из массива.
- $group: группирует документы в коллекции; может использоваться для получения статистических результатов.
- $sort: сортирует входные документы и выводит их.
- $geoNear: выводит упорядоченные документы, находящиеся рядом с определённым географическим местоположением.
Примеры операторов конвейера
1. Пример $project
db.article.aggregate(
{ $project : {
title : 1 ,
author : 1 ,
}}
);
Таким образом, результат содержит только три поля: _id, tilte и author. По умолчанию поле _id включается. Если вы не хотите включать _id, можно сделать так:
db.article.aggregate(
{ $project : {
_id : 0 ,
title : 1 ,
author : 1
}});
2. Пример $match
db.articles.aggregate( [
{ $match : { score : { $gt : 70, $lte : 90 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
] );
$match используется для получения записей, у которых значение scores больше 70 и меньше или равно 90, после чего подходящие записи передаются на следующий этап — оператор конвейера $group — для обработки.
3. Пример $skip
db.article.aggregate(
{ $skip : 5 });
После обработки оператором конвейера $skip первые пять документов «отфильтровываются».
Другие расширения