Un pipeline de agregación consta de uno o más Etapas que procesan los documentos:
Cada etapa realiza una operación sobre los documentos de entrada. Por ejemplo, una etapa puede filtrar documentos, agrupar documentos y calcular valores.
Los documentos que salen de una etapa pasan a la siguiente etapa.
Una canalización de agregación puede devolver resultados para grupos de documentos. Por ejemplo, devolver los valores total, promedio, máximo y mínimo.
Puedes actualizar documentos con una pipeline de agregación si utilizas las etapas mostradas en Actualizaciones con pipeline de agregación.
Nota
Las pipeline de agregación se ejecutan con el
db.collection.aggregate() método no modifica los documentos en la colección, salvo que el pipeline contenga una etapa $merge o una etapa $out.
Puedes ejecutar pipelines de agregación en la interfaz de usuario para implementaciones alojadas en MongoDB Atlas.
Cuando ejecutas pipelines de agregación en las implementaciones de MongoDB Atlas en la interfaz de usuario de MongoDB Atlas, puedes consultar una vista previa de los resultados en cada etapa.
Ejemplos completos de pipeline de agregación
Esta sección muestra ejemplos de pipeline de agregación que utilizan la siguiente colección orders de pizzas:
db.orders.insertMany( [ { _id: 0, name: "Pepperoni", size: "small", price: 19, quantity: 10, date: ISODate( "2021-03-13T08:14:30Z" ) }, { _id: 1, name: "Pepperoni", size: "medium", price: 20, quantity: 20, date : ISODate( "2021-03-13T09:13:24Z" ) }, { _id: 2, name: "Pepperoni", size: "large", price: 21, quantity: 30, date : ISODate( "2021-03-17T09:22:12Z" ) }, { _id: 3, name: "Cheese", size: "small", price: 12, quantity: 15, date : ISODate( "2021-03-13T11:21:39.736Z" ) }, { _id: 4, name: "Cheese", size: "medium", price: 13, quantity:50, date : ISODate( "2022-01-12T21:23:13.331Z" ) }, { _id: 5, name: "Cheese", size: "large", price: 14, quantity: 10, date : ISODate( "2022-01-12T05:08:13Z" ) }, { _id: 6, name: "Vegan", size: "small", price: 17, quantity: 10, date : ISODate( "2021-01-13T05:08:13Z" ) }, { _id: 7, name: "Vegan", size: "medium", price: 18, quantity: 10, date : ISODate( "2021-01-13T05:10:13Z" ) } ] )
Calcular la cantidad total del pedido
El siguiente ejemplo de pipeline de agregación contiene dos etapas y devuelve la cantidad total de órdenes de pizzas medianas agrupadas por nombre de pizza:
db.orders.aggregate( [ // Stage 1: Filter pizza order documents by pizza size { $match: { size: "medium" } }, // Stage 2: Group remaining documents by pizza name and calculate total quantity { $group: { _id: "$name", totalQuantity: { $sum: "$quantity" } } } ] )
La etapa $match:
Filtra los documentos de pedidos de pizza a pizzas con un
sizedemedium.Pasa los documentos restantes a la
$groupetapa.
La etapa $group:
Agrupa los documentos restantes por pizza
name.Utiliza
$sumpara calcular el pedido totalquantitypara cada pizzaname. El total se almacena en el campototalQuantitydevuelto por la pipeline de agregación.
Ejemplo de salida:
[ { _id: 'Cheese', totalQuantity: 50 }, { _id: 'Vegan', totalQuantity: 10 }, { _id: 'Pepperoni', totalQuantity: 20 } ]
Calcular el valor total del pedido y la cantidad promedio del pedido
El siguiente ejemplo calcula el valor total del pedido de pizza y la cantidad promedio de pedidos entre dos fechas:
db.orders.aggregate( [ // Stage 1: Filter pizza order documents by date range { $match: { "date": { $gte: new ISODate( "2020-01-30" ), $lt: new ISODate( "2022-01-30" ) } } }, // Stage 2: Group remaining documents by date and calculate results { $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } }, totalOrderValue: { $sum: { $multiply: [ "$price", "$quantity" ] } }, averageOrderQuantity: { $avg: "$quantity" } } }, // Stage 3: Sort documents by totalOrderValue in descending order { $sort: { totalOrderValue: -1 } } ] )
La etapa $match:
Filtra los documentos pedidos de pizza a aquellos en un rango de fechas especificado mediante
$gtey$lt.Pasa los documentos restantes a la
$groupetapa.
La etapa $group:
Agrupa los documentos por fecha
$dateToStringutilizando.Para cada grupo, calcula:
Valor total del pedido usando
$sumy$multiply.Cantidad promedio por pedido usando
$avg.
Pasa los documentos agrupados a la
$sortetapa.
La etapa $sort:
Ordena los documentos por el valor total del pedido para cada grupo en orden descendente (
-1).Devuelve los documentos ordenados.
Ejemplo de salida:
[ { _id: '2022-01-12', totalOrderValue: 790, averageOrderQuantity: 30 }, { _id: '2021-03-13', totalOrderValue: 770, averageOrderQuantity: 15 }, { _id: '2021-03-17', totalOrderValue: 630, averageOrderQuantity: 30 }, { _id: '2021-01-13', totalOrderValue: 350, averageOrderQuantity: 10 } ]
Más detalles de la etapa de pipeline de agregación
Una pipeline de agregación consta de una o más etapas que procesan documentos:
Una etapa no tiene que producir un documento por cada documento de entrada. Por ejemplo, algunas etapas pueden producir nuevos documentos o filtrar documentos existentes.
La misma etapa puede aparecer varias veces en la pipeline con estas excepciones de etapa:
$out,$mergey$geoNear.Para calcular promedios y realizar otros cálculos en una etapa, utilice expresiones de agregación que especifiquen operadores de agregación. Aprenderá más sobre las expresiones de agregación en la siguiente sección.
Para ver todas las etapas de agregación, consulta Etapas del pipeline de agregación.
Expresiones de canalización de agregación
Algunas etapas del pipeline de agregación aceptan una expresión de agregación, que:
Especifica la transformación que se aplicará a los documentos de entrada de la etapa actual.
Transforma los documentos en memoria.
Puede especificar operadores de expresión de agregación para calcular valores.
Puede contener expresiones de agregaciónadicionales anidadas.
Puedes utilizar los operadores de agregación $accumulator y $function para definir expresiones de agregación personalizadas en JavaScript.
Para todas las expresiones de agregación, consulta Expresiones.
Rutas de campos
Expresiones de ruta de campo se utilizan para acceder a campos en documentos de entrada. Para especificar una ruta de campo, antepón el nombre del campo o la ruta de campo punteada (si el campo está en un documento incrustado) con un signo de dólar $. Por ejemplo, "$user" para especificar la ruta de campo del campo user o "$user.name" para especificar la ruta de campo al campo "user.name" incrustado.
"$<field>" es equivalente a "$$CURRENT.<field>" donde la CURRENT es una variable del sistema que por defecto es la raíz del objeto actual, a menos que se indique lo contrario en etapas específicas.
Para obtener más información y ejemplos, consulta Rutas de campos.
Ejecuta una pipeline de agregación
Para ejecutar una canalización de agregación, utilice:
Actualiza documentos con una pipeline de agregación
Para actualizar documentos con una canalización de agregación, utilice:
Otras consideraciones
Limitaciones de la canalización de agregación
Una pipeline de agregación tiene limitaciones en los tipos de valores y en el tamaño del resultado. Consulta Límites de la pipeline de agregación.
Pipelines de agregación y colecciones fragmentadas
Una pipeline de agregación admite operaciones en colecciones fragmentadas. Consulta Pipelines de agregación y colecciones fragmentadas.
Pipelines de agregación como alternativa de map-reduce
A partir de MongoDB 5.0, map-reduce está obsoleto:
En vez de map-reduce, deberías usar un pipeline de agregación. Los pipelines de agregación proporcionan un mejor rendimiento y usabilidad que map-reduce.
Puedes reescribir las operaciones map-reduce mediante etapas de pipeline de agregación, como
$group,$mergey otras.Para las operaciones map-reduce que requieren una funcionalidad personalizada, puedes utilizar los operadores de agregación
$accumulatory$function. Puedes utilizar esos operadores para definir expresiones de agregación personalizadas en JavaScript.
Para ejemplos de alternativas de pipeline de agregación a map-reduce, consulte:
Obtén más información
Para obtener más información sobre las pipelines de agregación, consulta: