Агрегация в 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 первые пять документов «отфильтровываются».

Другие расширения