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ónDescripciónEjemplo
$sumCalcula la suma total.db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avgCalcula el promediodb.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$minObtiene el valor mínimo de los documentos de la colección.db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$maxObtiene el valor máximo de los documentos de la colección.db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$pushAgrega valores a un array sin comprobar si hay duplicados.db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSetAgrega 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"}}}])
$firstObtiene el primer documento según el orden de los documentos de origen.db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$lastObtiene 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