Привет, разработчики ?
В этом блоге мы изучим основы фреймворка агрегации MongoDB для фильтрации, сортировки, группировки и преобразования результатов работы с MongoDB. MongoDB помогает нам выполнять все эти операции с помощью конвейеров агрегации, которые представляют собой серию операций, последовательно обрабатывающих документы данных.
Для практики мы можем использовать — Mongo playground
Введите документы
[
{
"key": 1,
username: "saurabh",
age: 18,
languages: [
"c",
"c++"
]
},
{
"key": 2,
username: "leonord",
age: 22,
languages: [
"c",
"c++",
"java"
]
},
{
"key": 3,
username: "sheldon",
age: 14,
languages: [
"c",
"c++",
"java",
"python"
]
},
{
"key": 4,
username: "howard",
age: 32,
languages: [
"c",
"c++",
"java",
"python",
"dart"
]
},
{
"key": 5,
username: "raj",
age: 5,
languages: [
"c",
"c++",
"java",
"python",
"dart",
"ts"
]
}
]
1. $group aggregation = используется для группировки и суммирования документов. Мы должны указать поле _id
с допустимым выражением.
Запрос
db.collection.aggregate([
{
$group: {
_id: "table_stats",
// Get count of all docs in the collection
count: {
$sum: 1
},
// Get age stats by grouping age field
avgAge: {
$avg: "$age"
},
maxAge: {
$max: "$age"
},
minAge: {
$min: "$age"
},
sumAge: {
$sum: "$age"
},
// Get all usernames by grouping username field
allUsernames: {
$push: "$username"
},
// Get username of first doc
firstUsername: {
$first: "$username"
},
// Get username of last doc
lastUsername: {
$last: "$username"
}
}
}
])
Результат
[
{
"_id": "table_stats",
"allUsernames": [
"saurabh",
"leonord",
"sheldon",
"howard",
"raj"
],
"avgAge": 18.2,
"count": 5,
"firstUsername": "saurabh",
"lastUsername": "raj",
"maxAge": 32,
"minAge": 5,
"sumAge": 91
}
]
2. $match aggregation = Используется для уменьшения количества документов в результате путем фильтрации.
Запрос
// Match all docs where `age` is greater than 20 or equal to 20
db.collection.aggregate([
{
"$match": {
age: {
$gte: 20
}
}
}
])
Результат
[
{
"_id": ObjectId("5a934e000102030405000001"),
"age": 22,
"key": 2,
"languages": [
"c",
"c++",
"java"
],
"username": "leonord"
},
{
"_id": ObjectId("5a934e000102030405000003"),
"age": 32,
"key": 4,
"languages": [
"c",
"c++",
"java",
"python",
"dart"
],
"username": "howard"
}
]
Запрос
// Match all docs that have languages either `python` or `dart` or both
db.collection.aggregate([
{
"$match": {
languages: {
$in: [
"python",
"dart"
]
}
}
}
])
Результат
[
{
"_id": ObjectId("5a934e000102030405000002"),
"age": 14,
"key": 3,
"languages": [
"c",
"c++",
"java",
"python"
],
"username": "sheldon"
},
{
"_id": ObjectId("5a934e000102030405000003"),
"age": 32,
"key": 4,
"languages": [
"c",
"c++",
"java",
"python",
"dart"
],
"username": "howard"
},
{
"_id": ObjectId("5a934e000102030405000004"),
"age": 5,
"key": 5,
"languages": [
"c",
"c++",
"java",
"python",
"dart",
"ts"
],
"username": "raj"
}
]
Запрос
// Match all docs with username `saurabh`
db.collection.aggregate([
{
"$match": {
username: {
$eq: "saurabh"
}
}
}
])
Результат
[
{
"_id": ObjectId("5a934e000102030405000000"),
"age": 18,
"key": 1,
"languages": [
"c",
"c++"
],
"username": "saurabh"
}
]
Некоторые операторы соответствия
3. агрегация $skip и $limit = $skip принимает целое положительное число, задающее максимальное количество документов для пропуска. $limit ограничивает количество просматриваемых документов заданным числом, начиная с текущей позиции.
Без пропуска и ограничения
Запрос
// Get all docs with username lexicographically less than or equal to "saurabh"
db.collection.aggregate([
{
"$match": {
username: {
$lte: "saurabh"
}
}
},
// ignore this aggregation, for now, we'll look into it later
{
$project: {
"languages": 0,
"key": 0,
"id": 0
}
}
])
Результат
[
{
"_id": ObjectId("5a934e000102030405000000"),
"age": 18,
"username": "saurabh"
},
{
"_id": ObjectId("5a934e000102030405000001"),
"age": 22,
"username": "leonord"
},
{
"_id": ObjectId("5a934e000102030405000003"),
"age": 32,
"username": "howard"
},
{
"_id": ObjectId("5a934e000102030405000004"),
"age": 5,
"username": "raj"
}
]
Без пропуска = 1 и ограничения = 2
Запрос
// Skip the first doc ($skip) and return next 2 docs ($limit)
db.collection.aggregate([
{
"$match": {
username: {
$lte: "saurabh"
}
}
},
{
$skip: 1
},
{
$limit: 2
},
// ignore this aggregation for now
{
$project: {
"languages": 0,
"key": 0,
"id": 0
}
}
])
Результат
[
{
"_id": ObjectId("5a934e000102030405000001"),
"age": 22,
"username": "leonord"
},
{
"_id": ObjectId("5a934e000102030405000003"),
"age": 32,
"username": "howard"
}
]
4. $sort aggregation = Сортирует все входные документы и возвращает их в конвейер в отсортированном порядке.
1 = сортировать по возрастанию, -1 = сортировать по убыванию.
Запрос
// Get all the docs sorted in ascending order on the `age` field
db.collection.aggregate([
{
$sort: {
age: 1
}
},
// ignore this aggregation for now
{
$project: {
"languages": 0,
"key": 0,
"id": 0
}
}
])
Результат
[
{
"_id": ObjectId("5a934e000102030405000003"),
"age": 32,
"username": "howard"
},
{
"_id": ObjectId("5a934e000102030405000001"),
"age": 22,
"username": "leonord"
},
{
"_id": ObjectId("5a934e000102030405000000"),
"age": 18,
"username": "saurabh"
},
{
"_id": ObjectId("5a934e000102030405000002"),
"age": 14,
"username": "sheldon"
},
{
"_id": ObjectId("5a934e000102030405000004"),
"age": 5,
"username": "raj"
}
]
*5. $unwind aggregation * = Используется для разворачивания документов, в которых используются массивы.
Запрос
db.collection.aggregate([
{
$unwind: "$languages"
},
])
Результат
[
{
"_id": ObjectId("5a934e000102030405000000"),
"age": 18,
"key": 1,
"languages": "c",
"username": "saurabh"
},
{
"_id": ObjectId("5a934e000102030405000000"),
"age": 18,
"key": 1,
"languages": "c++",
"username": "saurabh"
},
{
"_id": ObjectId("5a934e000102030405000001"),
"age": 22,
"key": 2,
"languages": "c",
"username": "leonord"
},
{
"_id": ObjectId("5a934e000102030405000001"),
"age": 22,
"key": 2,
"languages": "c++",
"username": "leonord"
},
{
"_id": ObjectId("5a934e000102030405000001"),
"age": 22,
"key": 2,
"languages": "java",
"username": "leonord"
},
{
"_id": ObjectId("5a934e000102030405000002"),
"age": 14,
"key": 3,
"languages": "c",
"username": "sheldon"
},
{
"_id": ObjectId("5a934e000102030405000002"),
"age": 14,
"key": 3,
"languages": "c++",
"username": "sheldon"
},
{
"_id": ObjectId("5a934e000102030405000002"),
"age": 14,
"key": 3,
"languages": "java",
"username": "sheldon"
},
{
"_id": ObjectId("5a934e000102030405000002"),
"age": 14,
"key": 3,
"languages": "python",
"username": "sheldon"
},
{
"_id": ObjectId("5a934e000102030405000003"),
"age": 32,
"key": 4,
"languages": "c",
"username": "howard"
},
{
"_id": ObjectId("5a934e000102030405000003"),
"age": 32,
"key": 4,
"languages": "c++",
"username": "howard"
},
{
"_id": ObjectId("5a934e000102030405000003"),
"age": 32,
"key": 4,
"languages": "java",
"username": "howard"
},
{
"_id": ObjectId("5a934e000102030405000003"),
"age": 32,
"key": 4,
"languages": "python",
"username": "howard"
},
{
"_id": ObjectId("5a934e000102030405000003"),
"age": 32,
"key": 4,
"languages": "dart",
"username": "howard"
},
{
"_id": ObjectId("5a934e000102030405000004"),
"age": 5,
"key": 5,
"languages": "c",
"username": "raj"
},
{
"_id": ObjectId("5a934e000102030405000004"),
"age": 5,
"key": 5,
"languages": "c++",
"username": "raj"
},
{
"_id": ObjectId("5a934e000102030405000004"),
"age": 5,
"key": 5,
"languages": "java",
"username": "raj"
},
{
"_id": ObjectId("5a934e000102030405000004"),
"age": 5,
"key": 5,
"languages": "python",
"username": "raj"
},
{
"_id": ObjectId("5a934e000102030405000004"),
"age": 5,
"key": 5,
"languages": "dart",
"username": "raj"
},
{
"_id": ObjectId("5a934e000102030405000004"),
"age": 5,
"key": 5,
"languages": "ts",
"username": "raj"
}
]
Запрос
db.collection.aggregate([
{
$unwind: "$languages"
},
{
$match: {
username: "saurabh"
}
}
])
Результат
[
{
"_id": ObjectId("5a934e000102030405000000"),
"age": 18,
"key": 1,
"languages": "c",
"username": "saurabh"
},
{
"_id": ObjectId("5a934e000102030405000000"),
"age": 18,
"key": 1,
"languages": "c++",
"username": "saurabh"
}
]
6. Агрегация $project = Получить некоторые определенные поля из коллекции, задав ключам значения 0 (исключить) или 1 (включить).
Основной запрос
db.collection.aggregate([
{
$project: {
username: 1,
languages: 1
}
},
{
$unwind: "$languages"
},
{
$match: {
username: "saurabh"
}
}
])
Результат
[
{
"_id": ObjectId("5a934e000102030405000000"),
"languages": "c",
"username": "saurabh"
},
{
"_id": ObjectId("5a934e000102030405000000"),
"languages": "c++",
"username": "saurabh"
}
]
Запрос с обновлением имен столбцов
db.collection.aggregate([
{
$project: {
"system_username": "$username",
"system_languages": "$languages"
}
},
{
$unwind: "$system_languages"
},
{
$match: {
system_username: "saurabh"
}
}
])
Результат
[
{
"_id": ObjectId("5a934e000102030405000000"),
"system_languages": "c",
"system_username": "saurabh"
},
{
"_id": ObjectId("5a934e000102030405000000"),
"system_languages": "c++",
"system_username": "saurabh"
}
]
Следите за другими интересными статьями
- Hashnode
- Dev.to
Спасибо ?