Agregación en MongoDB
En MongoDB, la agregación se utiliza principalmente para procesar datos (como calcular promedios, sumas, etc.) y devolver los resultados calculados.
Es algo similarSQLen las sentenciascount(*)。
Método aggregate()
El método de agregación en MongoDB utiliza aggregate().
Sintaxis
El formato básico de sintaxis del método aggregate() es el siguiente:
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
Ejemplo
Los datos en la colección son los siguientes:
{
_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
},
Ahora, usando la colección anterior, calculamos el número de artículos escritos por cada autor con aggregate(); el resultado es el siguiente:
> 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
}
>
El ejemplo anterior es similar a la sentencia SQL:
select by_user, count(*) from mycol group by by_user
En el ejemplo anterior, agrupamos los datos por el campo by_user y calculamos la suma de los valores con el mismo by_user.
La siguiente tabla muestra algunas expresiones de agregación:
| Expresión | Descripción | Ejemplo |
|---|---|---|
| $sum | Calcula la suma total. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) |
| $avg | Calcula el promedio | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) |
| $min | Obtiene el valor mínimo de los documentos de la colección. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) |
| $max | Obtiene el valor máximo de los documentos de la colección. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) |
| $push | Agrega valores a un array sin comprobar si hay duplicados. | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) |
| $addToSet | Agrega valores a un array comprobando si hay duplicados; si el valor ya existe en el array, no se agrega. | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
| $first | Obtiene el primer documento según el orden de los documentos de origen. | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
| $last | Obtiene el último documento según el orden de los documentos de origen. | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
Concepto de pipeline
En Unix y Linux, el pipeline se usa generalmente para pasar la salida del comando actual como argumento al siguiente comando.
El pipeline de agregación de MongoDB procesa un documento y pasa el resultado al siguiente pipeline. Las operaciones del pipeline se pueden repetir.
Expresión: procesa un documento de entrada y produce una salida. Las expresiones no tienen estado; solo se usan para calcular documentos en el pipeline de agregación actual y no pueden procesar otros documentos.
Aquí presentamos varias operaciones comunes en el marco de agregación:
- $project: modifica la estructura de los documentos de entrada. Se puede usar para renombrar, agregar o eliminar campos, y también para crear resultados calculados y documentos anidados.
- $match: se usa para filtrar datos y solo genera los documentos que cumplen las condiciones. $match utiliza las operaciones de consulta estándar de MongoDB.
- $limit: se usa para limitar el número de documentos devueltos por el pipeline de agregación de MongoDB.
- $skip: omite el número especificado de documentos en el pipeline de agregación y devuelve los documentos restantes.
- $unwind: divide un campo de tipo array en un documento en múltiples documentos, cada uno con uno de los valores del array.
- $group: agrupa los documentos de la colección y se puede usar para resultados estadísticos.
- $sort: ordena los documentos de entrada y los genera.
- $geoNear: genera documentos ordenados cercanos a una ubicación geográfica determinada.
Ejemplos de operadores de pipeline
1. Ejemplo de $project
db.article.aggregate(
{ $project : {
title : 1 ,
author : 1 ,
}}
);
De esta manera, el resultado solo tendrá los campos _id, tilte y author. Por defecto, el campo _id está incluido. Si no se quiere incluir _id, se puede hacer así:
db.article.aggregate(
{ $project : {
_id : 0 ,
title : 1 ,
author : 1
}});
2. Ejemplo de $match
db.articles.aggregate( [
{ $match : { score : { $gt : 70, $lte : 90 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
] );
$match se usa para obtener registros con puntuación mayor que 70 y menor o igual que 90, y luego enviar los registros que cumplen la condición a la siguiente etapa del operador de pipeline $group para su procesamiento.
3. Ejemplo de $skip
db.article.aggregate(
{ $skip : 5 });
Después de procesar con el operador de pipeline $skip, los primeros cinco documentos son "filtrados".
Otras extensiones