Агрегация в информатике относится к процессу проверки контента, обработки и категоризации соответствующих данных и вывода результатов. Агрегация в MongoDB относится к процессу одновременной обработки, фильтрации и категоризации данных из нескольких документов и вывода результатов. В процессе операции агрегации данные подобны воде, протекающей по секционному конвейеру, поэтому агрегация в MongoDB также называется потоковой агрегацией.
MongoDB предоставляет несколько методов агрегации:
- Aggregation Pipeline
- Map-Reduce
- простая агрегация
Далее мы всесторонне рассмотрим агрегаты в MongoDB.
Aggregation Pipeline
Конвейер агрегации также известен как конвейер агрегации. Разработчики могут передавать несколько документов в одинStage
состоит изPipeline
,КаждыйStage
Результат обработки будет передан следующемуStage
средний, последнийStage
Результатом обработки является весьPipeline
Вывод.
Синтаксис создания конвейера агрегации следующий:
db.collection.aggregate( [ { <stage> }, ... ] )
MongoDB предоставляет 23 видаStage
,Они есть:
Stage | описывать |
---|---|
$addFields |
Добавьте новые поля в документ. |
$bucket |
Группирует входящие документы в соответствии с указанным выражением и границами корзины. |
$bucketAuto |
Автоматически определяет границы корзины, классифицируя входящие документы по определенному количеству групп на основе заданного выражения. |
$collStats |
Возвращает статистику о коллекции или представлении. |
$count |
Возвращает количество документов для этого этапа конвейера агрегации. |
$facet |
Обращайтесь с несколькими операциями агрегации в пределах одного фазы одного и того же набора входных документов. |
$geoNear |
Возвращает упорядоченный поток документов на основе близости к геопространственной точке. |
$graphLookup |
Выполните рекурсивный поиск по коллекции. |
$group |
Группирует документы по указанному выражению идентификатора. |
$indexStats |
Возвращает информацию индекса для коллекции. |
$limit |
Пройти немодифицированные первые N документы в трубопровод. |
$listSessions |
списокsystem.sessions Все сессии коллекции. |
$lookup |
Выполните левое внешнее соединение с другой коллекцией в той же базе данных. |
$match |
Фильтровать документы, позволяя передавать на следующий этап конвейера только соответствующие документы. |
$out |
Записывает результирующий документ конвейера агрегации в указанную коллекцию, которая должна быть последним этапом конвейера. |
$project |
Добавьте новые поля в документ или удалите существующие поля. |
$redact |
Может использоваться для реализации редактирования на уровне полей. |
$replaceRoot |
Заменить документ на указанный встроенный в документ. Это заменит любое существующее поле во входном документе, включая_id поле. Указывает документ, внедренный во входной документ, для продвижения внедренного документа на верхний уровень. |
$sample |
Случайным образом выбирает указанное количество документов из ввода. |
$skip |
Пропустить первые n документов и передать оставшиеся документы без изменений на следующий этап. |
$sort |
Переупорядочивает поток документов по указанному ключу сортировки. Меняется только порядок, файл остается прежним. Для каждого входного документа выведите один документ. |
$sortByCount |
Сгруппируйте входящие документы, затем подсчитайте количество документов в каждой отдельной группе. |
$unwind |
Деструктуризация полей массива в документе. |
Документация,Stage
иPipeline
Отношение показано на следующем рисунке:
$match
,$sample
и$project
подожди триStage
и процесс вывода. Общие термины агрегации в SQL:WHERE
,SUM
иCOUNT
Ждать. В следующей таблице описаны общие термины, функции и концепции агрегации SQL, а также соответствующие им операторы MongoDB илиStage
.
SQL | MongoDB |
---|---|
WHERE | $match |
GROUP BY | $group |
HAVING | $match |
SELECT | $project |
ORDER BY | $sort |
LIMIT | $limit |
SUM() | $sum |
COUNT() |
$sum $sortByCount
|
join | $lookup |
Ниже разберемся на примереAggregate
,Stage
иPipeline
Отношения между.
Простая концепция
$match
Описание гласит: «Фильтровать документы, позволяя передавать на следующий этап конвейера только соответствующие документы». Его синтаксис следующий:
{ $match: { <query> } }
Прежде чем приступить к обучению, нам необходимо подготовить следующие данные:
> db.artic.insertMany([
... { "_id" : 1, "author" : "dave", "score" : 80, "views" : 100 },
... { "_id" : 2, "author" : "dave", "score" : 85, "views" : 521 },
... { "_id" : 3, "author" : "anna", "score" : 60, "views" : 706 },
... { "_id" : 4, "author" : "line", "score" : 55, "views" : 300 }
... ])
Тогда мы строим только одинStage
изPipeline
, чтобы отфильтроватьauthor
заdave
документация. Соответствующий пример выглядит следующим образом:
> db.artic.aggregate([
... {$match: {author: "dave"}}
... ])
{ "_id" : 1, "author" : "dave", "score" : 80, "views" : 100 }
{ "_id" : 2, "author" : "dave", "score" : 85, "views" : 521 }
Если вы хотите создать дваStage
изPipeline
, затем вaggregate
добавитьStage
Вот и все. Сейчас такая потребность: сбор статистикиartic
серединаscore
больше, чем70
и меньше чем90
количество документов. Это требование выполняется в два этапа:
- Отфильтруйте документы, соответствующие вашим требованиям
- Подсчитайте количество документов
Агрегация идеально подходит для этой многоэтапной операции. В этом сценарии нам нужно использовать$match
,$group
эти двоеStage
, а затем с помощью агрегатного выражения$sum
В совокупности соответствующие примеры выглядят следующим образом:
> db.artic.aggregate([
... {$match: {score: {$gt: 70, $lt: 90}}},
... {$group: {_id: null, number: {$sum: 1}}}
... ])
{ "_id" : null, "number" : 2 }
Полный процесс этого примера может быть представлен следующей схемой:
Благодаря приведенному выше описанию и примерам я считаю, что вы правы.Aggregate
,Stage
иPipeline
иметь определенное понимание. Далее мы изучим общиеStage
синтаксис и использование.
Общая сцена
sample
$sample
Роль состоит в том, чтобы случайным образом выбрать указанное количество документов из ввода, и его синтаксис выглядит следующим образом:
{ $sample: { size: <positive integer> } }
Предположим, вы хотите получить из коллекцииartic
Из списка случайным образом выбираются два документа, соответствующие примеры таковы:
> db.artic.aggregate([
... {$sample: {size: 2}}
... ])
{ "_id" : 1, "author" : "dave", "score" : 80, "views" : 100 }
{ "_id" : 3, "author" : "anna", "score" : 60, "views" : 706 }
size
Соответствующее значение должно быть целым положительным числом. Если вы введете отрицательное число, вы получите сообщение об ошибке:size argument to $sample must not be negative
. Обратите внимание, что когда значение превышает количество документов в коллекции, возвращаются все документы в коллекции, но порядок документов является случайным.
project
$project
Роль заключается в фильтрации полей в документе, что аналогично операции проецирования, но результаты обработки будут переданы на следующий этап. Его синтаксис следующий:
{ $project: { <specification(s)> } }
Подготовьте следующие данные:
> db.projects.save(
{_id: 1, title: "篮球训练营青春校园活动开始啦", numb: "A829Sck23", author: {last: "quinn", first: "James"}, hot: 35}
)
ПредположениеPipeline
следующий вStage
Просто нужна документацияtitle
иauthor
поля, соответствующие примеры выглядят следующим образом:
> db.projects.aggregate([{$project: {title: 1, author: 1}}])
{ "_id" : 1, "title" : "篮球训练营青春校园活动开始啦", "author" : { "last" : "quinn", "first" : "James" } }
0
и1
могут существовать одновременно. Соответствующий пример выглядит следующим образом:
> db.projects.aggregate([{$project: {title: 1, author: 1, _id: 0}}])
{ "title" : "篮球训练营青春校园活动开始啦", "author" : { "last" : "quinn", "first" : "James" } }
true
равно1
,false
равно0
, вы также можете смешивать логические значения и числа, соответствующие примеры выглядят следующим образом:
> db.projects.aggregate([{$project: {title: 1, author: true, _id: false}}])
{ "title" : "篮球训练营青春校园活动开始啦", "author" : { "last" : "quinn", "first" : "James" } }
Если вы хотите исключить указанные поля, то в$project
установить его на0
илиfalse
Тогда соответствующий пример выглядит следующим образом:
> db.projects.aggregate([{$project: {author: false, _id: false}}])
{ "title" : "篮球训练营青春校园活动开始啦", "numb" : "A829Sck23", "hot" : 35 }
$project
Также работает со встроенными документами. заauthor
поля, иногда нам просто нужноFirstName
илиLastname
, соответствующий пример выглядит следующим образом:
> db.projects.aggregate([{$project: {author: {"last": false}, _id: false, numb: 0}}])
{ "title" : "篮球训练营青春校园活动开始啦", "author" : { "first" : "James" }, "hot" : 35 }
использовать здесь{author: {"last": false}}
ОтфильтрованоLastName
, но держиfirst
.
Вышеупомянутое$project
Введение в основное использование и функции , больше с$project
Соответствующие знания можно найти в официальной документации$project.
lookup
$lookup
Роль заключается в выполнении левого внешнего соединения коллекций в той же базе данных, и его синтаксис выглядит следующим образом:
{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
as: <output array field>
}
}
Левое внешнее соединение выглядит как следующий оператор псевдо-SQL:
SELECT *, <output array field>
FROM collection WHERE <output array field> IN (
SELECT * FROM <collection to join> WHERE
<foreignField>= <collection.localField>);
lookup
Ниже приведены поддерживаемые команды и соответствующие им описания:
поле | описывать |
---|---|
from |
Задает имя коллекции. |
localField |
Укажите ввод$lookup поля в . |
foreignField |
уточнитьfrom Поля документа в данной коллекции. |
as |
Задает имя нового массива полей, добавляемых во входной документ. Новое поле массива содержит from совпадающие документы в коллекции.Если указанное имя уже существует во входном документе, существующее поле будет перезаписано. |
Подготовьте следующие данные:
> db.sav.insert([
{ "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 },
{ "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 },
{ "_id" : 3 }
])
> db.avi.insert([
{ "_id" : 1, "sku" : "almonds", description: "product 1", "instock" : 120 },
{ "_id" : 2, "sku" : "bread", description: "product 2", "instock" : 80 },
{ "_id" : 3, "sku" : "cashews", description: "product 3", "instock" : 60 },
{ "_id" : 4, "sku" : "pecans", description: "product 4", "instock" : 70 },
{ "_id" : 5, "sku": null, description: "Incomplete" },
{ "_id" : 6 }
])
Предположим, вы хотите присоединиться к коллекциямsav
серединаitem
и коллекцияavi
серединаsku
, и назовите объединенный результат какsavi
. Соответствующий пример выглядит следующим образом:
> db.sav.aggregate([
{
$lookup:
{
from: "avi",
localField: "item",
foreignField: "sku",
as: "savi"
}
}
])
После выполнения команды вывод будет следующим:
{
"_id" : 1,
"item" : "almonds",
"price" : 12,
"quantity" : 2,
"savi" : [
{ "_id" : 1, "sku" : "almonds", "description" : "product 1", "instock" : 120 }
]
}
{
"_id" : 2,
"item" : "pecans",
"price" : 20,
"quantity" : 1,
"savi" : [
{ "_id" : 4, "sku" : "pecans", "description" : "product 4", "instock" : 70 }
]
}
{
"_id" : 3,
"savi" : [
{ "_id" : 5, "sku" : null, "description" : "Incomplete" },
{ "_id" : 6 }
]
}
Приведенная выше операция соединения эквивалентна следующему псевдо-SQL:
SELECT *, savi
FROM sav
WHERE savi IN (SELECT *
FROM avi
WHERE sku= sav.item);
Вышеупомянутоеlookup
Введение в основное использование и функции , больше сlookup
Соответствующие знания можно найти в официальной документацииlookup.
unwind
unwind
Документ, содержащий массив, можно разделить на несколько документов, и его синтаксис выглядит следующим образом:
{
$unwind:
{
path: <field path>,
includeArrayIndex: <string>,
preserveNullAndEmptyArrays: <boolean>
}
}
unwind
Ниже приведены поддерживаемые команды и соответствующие им описания:
инструкция | тип | описывать |
---|---|---|
path |
string | Указывает путь к полю поля массива, обязательно. |
includeArrayIndex |
string | Имя нового поля для хранения индекса массива элемента. |
preserveNullAndEmptyArrays |
boolean | По умолчанию, еслиpath заnull , отсутствует это поле или пустой массив, документ не выводится. Вместо этого установите его наtrue документ будет выведен. |
Прежде чем приступить к обучению, нам необходимо подготовить следующие данные:
> db.shoes.save({_id: 1, brand: "Nick", sizes: [37, 38, 39]})
собиратьshoes
серединаsizes
представляет собой массив с данными нескольких размеров. Предположим, вы хотите разделить этот документ на 3size
Документ с одним значением, соответствующий пример выглядит следующим образом:
> db.shoes.aggregate([{$unwind : "$sizes"}])
{ "_id" : 1, "brand" : "Nick", "sizes" : 37 }
{ "_id" : 1, "brand" : "Nick", "sizes" : 38 }
{ "_id" : 1, "brand" : "Nick", "sizes" : 39 }
Очевидно, что такой документ нам удобнее для обработки данных.preserveNullAndEmptyArrays
По умолчанию командаfalse
Что указано в документеpath
Пусто,null
или отсутствуетpath
, документ будет проигнорирован. Предположим, что данные следующие:
> db.shoes2.insertMany([
{"_id": 1, "item": "ABC", "sizes": ["S", "M", "L"]},
{"_id": 2, "item": "EFG", "sizes": [ ]},
{"_id": 3, "item": "IJK", "sizes": "M"},
{"_id": 4, "item": "LMN" },
{"_id": 5, "item": "XYZ", "sizes": null}
])
Выполняем следующие команды:
> db.shoes2.aggregate([{$unwind: "$sizes"}])
Вы получите следующий вывод:
{ "_id" : 1, "item" : "ABC", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC", "sizes" : "L" }
{ "_id" : 3, "item" : "IJK", "sizes" : "M" }
_id
за2
,4
и5
документация должна удовлетворитьpreserveNullAndEmptyArrays
состоянии, поэтому он не будет разделен.
Вышеупомянутоеunwind
Введение в основное использование и функции , больше сunwind
Соответствующие знания можно найти в официальной документацииunwind.
out
out
роль агрегацииPipeline
Возвращает результирующий документ и записывает его в указанную коллекцию. Чтобы быть осторожным,out
Действие должно появиться вPipeline
последний.out
Синтаксис следующий:
{ $out: "<output-collection>" }
Подготовьте следующие данные:
> db.books.insertMany([
{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 },
{ "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 },
{ "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 },
{ "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 },
{ "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
])
предполагается собратьbooks
Результаты группировки сохраняются в файл с именемbooks_result
В наборе соответствующие примеры следующие:
> db.books.aggregate([
... { $group : {_id: "$author", books: {$push: "$title"}}},
... { $out : "books_result" }
... ])
После выполнения команды MongoDB создастbooks_result
коллекции и сохраните результаты группировки в эту коллекцию. собиратьbooks_result
Документация в следующем:
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
Вышеупомянутоеout
Введение в основное использование и функции , больше сout
Соответствующие знания можно найти в официальной документацииout.
Map-Reduce
Map-reduce используется для сжатия больших объемов данных в полезные агрегированные результаты, и его синтаксис выглядит следующим образом:
db.runCommand(
{
mapReduce: <collection>,
map: <function>,
reduce: <function>,
finalize: <function>,
out: <output>,
query: <document>,
sort: <document>,
limit: <number>,
scope: <document>,
jsMode: <boolean>,
verbose: <boolean>,
bypassDocumentValidation: <boolean>,
collation: <document>,
writeConcern: <document>
}
)
в,db.runCommand({mapReduce: <collection>})
также можно записать какdb.collection.mapReduce()
. Соответствующее описание каждой команды выглядит следующим образом:
инструкция | тип | описывать |
---|---|---|
mapReduce |
collection | Название коллекции, обязательно. |
map |
function | Функции JavaScript требуются. |
reduce |
function | Требуется функция JavaScript. |
out |
string or document | Укажите требуемый результат вывода. |
query |
document | Оператор условия запроса. |
sort |
document | Сортировать документы. |
limit |
number | Укажите ввод дляmap Максимальное количество документов. |
finalize |
function | Исправлятьreduce Вывод. |
scope |
document | Укажите глобальные переменные. |
jsMode |
boolean | Выполняется лиmap иreduce Преобразование промежуточных данных в формат BSON между функциями, по умолчаниюfalse . |
verbose |
boolean | Содержит ли результатtiming информация, по умолчаниюfalse . |
bypassDocumentValidation |
boolean | Это разрешеноmapReduce Обход проверки документов во время работы, по умолчаниюfalse . |
collation |
document | Указывает, что использовать для операциисопоставление. |
writeConcern |
document | Укажите уровень записи, в противном случае используйте уровень по умолчанию. |
Простая картаУменьшить
ПростоmapReduce
Примеры синтаксиса следучены следующим образом:
var mapFunction = function() { ... };
var reduceFunction = function(key, values) { ... };
db.runCommand(
... {
... ... mapReduce: <input-collection>,
... ... map: mapFunction,
... ... reduce: reduceFunction,
... ... out: { merge: <output-collection> },
... ... query: <query>
... })
map
Каждая функция отвечает за преобразование входного документа в ноль или более документов.map
Структура выглядит следующим образом:
function() {
...
emit(key, value);
}
emit
Роль функции заключается в группировке, она принимает два параметра:
-
key
: указывает поле, которое будет использоваться для группировки. -
value
: Поле для агрегирования.
существуетmap
можно использовать вthis
Ключевое слово относится к текущему документу.reduce
Структура выглядит следующим образом:
function(key, values) {
...
return result;
}
reduce
Выполните конкретную операцию обработки данных, она получает два параметра:
-
key
:иmap
серединаkey
То же, поле группировки. -
values
: По полю группировки будет одинаковоkey
поместите значения в тот же массив,values
это объект, который содержит эти категориальные массивы.
out
для указания вывода результата,out: <collectionName>
выведет результат в новую коллекцию или использует следующий синтаксис для вывода результата в существующую коллекцию:
out: { <action>: <collectionName>
[, db: <dbName>]
[, sharded: <boolean> ]
[, nonAtomic: <boolean> ] }
Обратите внимание, что еслиout
назначенныйcollection
уже существует, то он перезаписывает коллекцию. Прежде чем приступить к обучению, нам необходимо подготовить следующие данные:
> db.mprds.insertMany([
... {_id: 1, numb: 3, score: 9, team: "B"},
... {_id: 2, numb: 6, score: 9, team: "A"},
... {_id: 3, numb: 24, score: 9, team: "A"},
... {_id: 4, numb: 6, score: 8, team: "A"}
... ])
Затем определитеmap
функция,reduce
функцию и применить ее к коллекцииmrexample
начальство. Затем укажите место хранения для результата вывода, где результат вывода хранится в файле с именемmrexample_result
в коллекции.
> var func_map = function(){emit(this.numb, this.score);};
> var func_reduce = function(key, values){return Array.sum(values);};
> db.mprds.mapReduce(func_map, func_reduce, {query: {team: "A"}, out: "mprds_result"})
map
Функция указывает два ключа, которые должны быть включены в результат, и устанавливаетthis.class
Тот же документ выводится в тот же документ.reduce
Затем входящий список суммируется, а результат суммирования используется как результат в результате.value
. После выполнения команды результат будет сохранен в коллекцииmprds_result
середина. Просмотрите результаты с помощью следующей команды:
> db.mprds_result.find()
{ "_id" : 6, "value" : 17 }
{ "_id" : 24, "value" : 9 }
Документ_id
которыйmap
серединаthis.numb
,value
заreduce
Возвращаемое значение функции.
Рисунок ниже описываетmapReduce
Полный процесс эксплуатации:
завершить обрезку
finallize
для модификацииreduce
Выходной результат, его синтаксический формат выглядит следующим образом:
function(key, reducedValue) {
...
return modifiedObject;
}
Он принимает два параметра:
key
,иmap
серединаkey
То же, поле группировки.
reducedValue
,ОдинObecjt
,Даreduce
Вывод.
Выше мы представилиmap
иreduce
, и понять на простом примереmapReduce
Основной состав и использование. На самом деле, мы также можем написать более многофункциональныйreduce
функционировать, даже используяfinallize
Исправлятьreduce
выходной результат. следующееreduce
функция будет передана вvalues
выполнять вычисления и реорганизацию, возвращаяreduceVal
Объект:
> var func_reduce2 = function(key, values){
reduceVal = {team: key, score: values, total: Array.sum(values), count: values.length};
return reduceVal;
};
reduceVal
Объект содержитteam
,score
,total
иcount
четыре свойства. но мы также хотим добавитьavg
свойства, то вы можетеfinallize
выполнять в функцииavg
Расчет стоимости иavg
Добавление свойств работает:
> var func_finalize = function(key, values){
values.avg = values.total / values.count;
return values;
};
map
Не изменяйте, примените эти функции к коллекцииmprds
выше соответствующий пример выглядит следующим образом:
> db.mprds.mapReduce(func_map, func_reduce2, {query: {team: "A"}, out: "mprds_result", finalize: func_finalize})
После выполнения команды результат будет сохранен в указанной коллекции. На данный момент коллекцияmprds_result
Содержание следующее:
{ "_id" : 6, "value" : { "team" : 6, "score" : [ 9, 8 ], "total" : 17, "count" : 2, "avg" : 8.5 } }
{ "_id" : 24, "value" : 9 }
Рисунок ниже описываетmapReduce
Полный процесс эксплуатации:
finallize
существуетreduce
последующее использование, тонкая настройкаreduce
результат обработки. Похоже, садовник подстригает клумбу, поэтому людиfinallize
Образно называется «обрезка».
Будьте осторожны:map
будетkey
в документе с одинаковым значениемvalue
Введенный в тот же объект, этот объект будет проходить черезreduce
иfinallize
. заkey
те документы, значение которых уникально, указанныеkey
иvalue
будут выведены напрямую.
простая агрегация
В дополнение к сложным операциям агрегации, таким как Aggregation Pipeline и Map-Reduce, MongoDB также поддерживает некоторые простые операции агрегации, такие какcount
,group
иdistinct
Ждать.
count
count
Используется для подсчета количества документов в коллекции или представлении, возвращает документ, содержащий результат подсчета и статус. Его синтаксис следующий:
{
count: <collection or view>,
query: <document>,
limit: <integer>,
skip: <integer>,
hint: <hint>,
readConcern: <document>
}
count
Ниже приведены поддерживаемые команды и соответствующие им описания:
инструкция | тип | описывать |
---|---|---|
count |
string | Обязательное имя коллекции или представления для подсчета. |
query |
document | Оператор условия запроса. |
limit |
integer | Указывает максимальное количество возвращаемых совпадающих документов. |
skip |
integer | Указывает количество совпадающих документов, которые необходимо пропустить перед возвратом результатов. |
hint |
string or document | Укажите используемый индекс, указав имя индекса в виде строки или документа спецификации индекса. |
Предположим, вы хотите подсчитать коллекциюmprds
Количество документов в соответствующих примерах следующее:
> db.runCommand({count: 'mprds'})
{ "n" : 4, "ok" : 1 }
Предположим, вы хотите подсчитать коллекциюmprds
серединаnumb
за6
Количество документов, соответствующих примеров, следующее:
> db.runCommand({count: 'mprds', query: {numb: {$eq: 6}}})
{ "n" : 2, "ok" : 1 }
Указывает пропустить перед возвратом результатов1
документы, соответствующие примеры следующие:
> db.runCommand({count: 'mprds', query: {numb: {$eq: 6}}, skip: 1})
{ "n" : 1, "ok" : 1 }
больше оcount
Знания можно найти в официальной документацииCount.
group
group
Роль состоит в том, чтобы сгруппировать документы в коллекции по указанному ключу и выполнить простую агрегатную функцию, аналогичную той, что используется в SQL.SELECT ... GROUP BY
похожий. Его синтаксис следующий:
{
group:
{
ns: <namespace>,
key: <key>,
$reduce: <reduce function>,
$keyf: <key function>,
cond: <query>,
finalize: <finalize function>
}
}
group
Ниже приведены поддерживаемые команды и соответствующие им описания:
инструкция | тип | описывать |
---|---|---|
ns |
string | Требуется коллекция групп выполнения по операциям. |
key |
ducoment | Поле или поля для группировки, обязательные. |
$reduce |
function | Функция для выполнения операций агрегирования документов во время операций группировки. Функция принимает два аргумента: текущий документ и агрегированный результирующий документ для группы. Необходимые. |
initial |
document | Инициализировать документ результата агрегации, если требуется. |
$keyf |
function | альтернативаkey . Определяет функцию, используемую для создания "ключевого объекта" для использования в качестве ключа группировки.использовать $keyf вместоkey Сгруппировано по вычислительному полю вместо существующих полей документа. |
cond |
document | Критерии выбора для определения того, какие документы в коллекции следует обрабатывать. Если опущено, group Все документы коллекции обработаны. |
finalize |
function | Запустите перед возвратом результата, эта функция может изменить результирующий документ. |
Подготовьте следующие данные:
> db.sales.insertMany([
{_id: 1, orderDate: ISODate("2012-07-01T04:00:00Z"), shipDate: ISODate("2012-07-02T09:00:00Z"), attr: {name: "新款椰子鞋", price: 2999, size: 42, color: "香槟金"}},
{_id: 2, orderDate: ISODate("2012-07-03T05:20:00Z"), shipDate: ISODate("2012-07-04T09:00:00Z"), attr: {name: "高邦篮球鞋", price: 1999, size: 43, color: "狮王棕"}},
{_id: 3, orderDate: ISODate("2012-07-03T05:20:10Z"), shipDate: ISODate("2012-07-04T09:00:00Z"), attr: {name: "新款椰子鞋", price: 2999, size: 42, color: "香槟金"}},
{_id: 4, orderDate: ISODate("2012-07-05T15:11:33Z"), shipDate: ISODate("2012-07-06T09:00:00Z"), attr: {name: "极速跑鞋", price: 500, size: 43, color: "西湖蓝"}},
{_id: 5, orderDate: ISODate("2012-07-05T20:22:09Z"), shipDate: ISODate("2012-07-06T09:00:00Z"), attr: {name: "新款椰子鞋", price: 2999, size: 42, color: "香槟金"}},
{_id: 6, orderDate: ISODate("2012-07-05T22:35:20Z"), shipDate: ISODate("2012-07-06T09:00:00Z"), attr: {name: "透气网跑", price: 399, size: 38, color: "玫瑰红"}}
])
Предположим, вы хотите, чтобы коллекцииsales
Документация вattr.name
Группировка и ограничение количества документов, участвующих в группировкеshipDate
больше указанного времени. Соответствующий пример выглядит следующим образом:
> db.runCommand({
group:{
ns: 'sales',
key: {"attr.name": 1},
cond: {shipDate: {$gt: ISODate('2012-07-04T00:00:00Z')}},
$reduce: function(curr, result){},
initial: {}
}
})
После выполнения команды будет возвращен файл результатов. в,retval
Включить указанные поляattr.name
Данные,count
- количество документов, участвующих в группировке,keys
представляет количество групп,ok
Представляет статус документа. В результате документ выглядит следующим образом:
{
"retval" : [
{
"attr.name" : "高邦篮球鞋"
},
{
"attr.name" : "新款椰子鞋"
},
{
"attr.name" : "极速跑鞋"
},
{
"attr.name" : "透气网跑"
}
],
"count" : NumberLong(5),
"keys" : NumberLong(4),
"ok" : 1
}
Указано в примере вышеkey
даattr.name
. Поскольку только 2 из 5 документов, участвующих в группировкеattr.name
Одинаково, результаты группировкиkeys
за4
, который представляет наборsales
Документы в разделе разделены на 4 группы.
будетattr.name
заменитьshipDate
Смотрите, результаты будут такими, какие они есть. Соответствующий пример выглядит следующим образом:
> db.runCommand(
{
group:{
ns: 'sales',
key: {shipDate: 1},
cond: {shipDate: {$gt: ISODate('2012-07-04T00:00:00Z')}},
$reduce: function(curr, result){},
initial: {}
}
}
)
После выполнения команды возвращаются следующие результаты:
{
"retval" : [
{
"shipDate" : ISODate("2012-07-04T09:00:00Z")
},
{
"shipDate" : ISODate("2012-07-06T09:00:00Z")
}
],
"count" : NumberLong(5),
"keys" : NumberLong(2),
"ok" : 1
}
Поскольку несколько из 5 документов, участвующих в группировкеshipDate
являются дубликатами, поэтому в сгруппированном результатеkeys
за2
, который представляет наборsales
Документ разделен на 2 группы.
В приведенном выше примере не используетсяreduce
,initial
иfinallize
, далее мы продемонстрируем их использование и роль. Предположим, вы хотите подсчитать общий объем продаж одной и той же группы, тогда вы можетеreduce
Выполнение определенной логики расчета в . Соответствующий пример выглядит следующим образом:
> db.runCommand(
{
group:{
ns: 'sales',
key: {shipDate: 1},
cond: {shipDate: {$gt: ISODate('2012-07-04T00:00:00Z')}},
$reduce: function(curr, result){
result.total += curr.attr.price;
},
initial: {total: 0}
}
}
)
После выполнения команды возвращаемый результат выглядит следующим образом:
{
"retval" : [
{
"shipDate" : ISODate("2012-07-04T09:00:00Z"),
"total" : 4998
},
{
"shipDate" : ISODate("2012-07-06T09:00:00Z"),
"total" : 3898
}
],
"count" : NumberLong(5),
"keys" : NumberLong(2),
"ok" : 1
}
Искусственная проверка, дата доставкиshipDate
больше, чем2012-07-04T09:00:00Z
Документация:
{ "_id" : 2, "orderDate" : ISODate("2012-07-03T05:20:00Z"), "shipDate" : ISODate("2012-07-04T09:00:00Z"), "attr" : { "name" : "高邦篮球鞋", "price" : 1999, "size" : 43, "color" : "狮王棕" } }
{ "_id" : 3, "orderDate" : ISODate("2012-07-03T05:20:10Z"), "shipDate" : ISODate("2012-07-04T09:00:00Z"), "attr" : { "name" : "新款椰子鞋", "price" : 2999, "size" : 42, "color" : "香槟金" } }
Общий объем продаж1999 + 2999 = 4998
, что совпадает с возвращаемым результатом. Дата отправкиshipDate
больше, чем2012-07-06T09:00:00Z
Документация:
{ "_id" : 4, "orderDate" : ISODate("2012-07-05T15:11:33Z"), "shipDate" : ISODate("2012-07-06T09:00:00Z"), "attr" : { "name" : "极速跑鞋", "price" : 500, "size" : 43, "color" : "西湖蓝" } }
{ "_id" : 5, "orderDate" : ISODate("2012-07-05T20:22:09Z"), "shipDate" : ISODate("2012-07-06T09:00:00Z"), "attr" : { "name" : "新款椰子鞋", "price" : 2999, "size" : 42, "color" : "香槟金" } }
{ "_id" : 6, "orderDate" : ISODate("2012-07-05T22:35:20Z"), "shipDate" : ISODate("2012-07-06T09:00:00Z"), "attr" : { "name" : "透气网跑", "price" : 399, "size" : 38, "color" : "玫瑰红" } }
Общий объем продаж500 + 2999 + 399 = 3898
, что совпадает с возвращаемым результатом.
Иногда может возникнуть необходимость подсчитать количество документов в каждой группе и рассчитать средние продажи.Соответствующие примеры приведены ниже:
> db.runCommand(
{
group:{
ns: 'sales',
key: {shipDate: 1},
cond: {shipDate: {$gt: ISODate('2012-07-04T00:00:00Z')}},
$reduce: function(curr, result){
result.total += curr.attr.price;
result.count ++;
},
initial: {total: 0, count: 0},
finalize: function(result){
result.avg = Math.round(result.total / result.count);
}
}
}
)
Приведенный выше пример изменился$reduce
функция для статистических целейcount
. а затем добавилfinalize
Цель состоит в том, чтобы рассчитать средние продажи в группе. После выполнения команды верните следующую документацию:
{
"retval" : [
{
"shipDate" : ISODate("2012-07-04T09:00:00Z"),
"total" : 4998,
"count" : 2,
"avg" : 2499
},
{
"shipDate" : ISODate("2012-07-06T09:00:00Z"),
"total" : 3898,
"count" : 3,
"avg" : 1299
}
],
"count" : NumberLong(5),
"keys" : NumberLong(2),
"ok" : 1
}
Вышеупомянутоеgroup
Введение в основное использование и функции , больше сgroup
Соответствующие знания можно найти в официальной документацииgroup.
distinct
distinct
Роль заключается в том, чтобы найти различные значения указанного поля в одной коллекции, и его синтаксис выглядит следующим образом:
{
distinct: "<collection>",
key: "<field>",
query: <query>,
readConcern: <read concern document>,
collation: <collation document>
}
distinct
Ниже приведены поддерживаемые команды и соответствующие им описания:
инструкция | тип | описывать |
---|---|---|
distinct |
string | Название коллекции, обязательно. |
key |
string | Указанное поле является обязательным. |
query |
document | Оператор условия запроса. |
readConcern |
document | |
collation |
document |
Подготовьте следующие данные:
> db.dress.insertMany([
... {_id: 1, "dept": "A", attr: {"款式": "立领", color: "red" }, sizes: ["S", "M" ]},
... {_id: 2, "dept": "A", attr: {"款式": "圆领", color: "blue" }, sizes: ["M", "L" ]},
... {_id: 3, "dept": "B", attr: {"款式": "圆领", color: "blue" }, sizes: "S" },
... {_id: 4, "dept": "A", attr: {"款式": "V领", color: "black" }, sizes: ["S" ] }
])
Предположим, вы хотите подсчитать коллекциюdress
всех документов вdept
Различные значения поля, соответствующие примеры следующие:
> db.runCommand ( { distinct: "dress", key: "dept" } )
{ "values" : [ "A", "B" ], "ok" : 1 }
Или посмотрите на эти стили, соответствующие примеры приведены ниже.
> db.runCommand ( { distinct: "dress", key: "attr.款式" } )
{ "values" : [ "立领", "圆领", "V领" ], "ok" : 1 }
Даже если значение представляет собой массив,distinct
С ним также можно обращаться правильно, и соответствующие примеры таковы:
> db.runCommand ( { distinct: "dress", key: "sizes" } )
{ "values" : [ "M", "S", "L" ], "ok" : 1 }
Сводка операций потокового агрегирования
Вышеизложенное является введением в операции потоковой агрегации в MongoDB в этой статье. Понятия агрегатов и конвейеров не являются общими, но их нетрудно понять. Если вы будете следовать примерам и практиковаться, я уверен, что вскоре вы сможете освоить операцию агрегирования.
Не можете видеть достаточно?
Помимо того, что я помог вам освоить операции потоковой агрегации, я также написал полный набор руководств по началу работы с MongoDB.После прочтения руководств вы получите:
- CRUD-операции и объекты Cursor для документов
- Освойте операции потоковой агрегации и легко справляйтесь с любыми потребностями в обработке данных
- Узнайте об эффективности запросов и оптимизации в MongoDB
- Научитесь улучшать удобство использования MongoDB
- Научитесь справляться со сбоями службы данных
- Понимание контроля доступа MongoDB
- Научитесь использовать модели данных, чтобы уменьшить избыточность данных и повысить эффективность
- Освойте методы резервного копирования и восстановления данных mongodump
Серия руководств по MongoDB подходит для людей
- 0 основных разработчиков, заинтересованных в MongoDB
- Разработчики, у которых есть определенный фундамент и которые хотят полностью понять MongoDB
Почему стоит выбрать этот набор руководств по MongoDB?
- Учебники MongoDB с аналогичным содержанием могут стоить сотни долларов на каждом шагу
- Официальная документация MongoDB неясна
- Другие статьи в Интернете недостаточно полны для формирования систематических знаний.
- Образец кода в чате можно скопировать и использовать напрямую, что удобно для практики
- В MongoDB много контента, и самообучающиеся не знают, что изучать
Это статья о быстром старте MongoDB, написанная для 0 студентов начального уровня. От документирования CRUD до операций потоковой агрегации; от планов выполнения, индексов, моделей данных до наборов реплик; от сегментирования, контроля доступа до резервного копирования и восстановления данных. Содержание почти 50 000 слов во всей статье охватывает большую часть знаний о MongoDB и полностью соответствует требованиям ежедневной разработки.
Прежде всего, этот набор учебных пособий стоит 9,9 юаня.
Вы можете добавить автора WeChat: DomFreez и пожаловаться на автора.
На данный момент приняли участие более 600 друзей