Overview
En esta guía, puedes aprender cómo usar la Biblioteca PHP de MongoDB para realizar operaciones de agregación.
Las operaciones de agregación procesan datos en tus colecciones de MongoDB y devuelven resultados calculados. El marco de agregación de MongoDB, que forma parte de la API de query, está basado en el concepto de pipelines de procesamiento de datos. Los documentos ingresan a un pipeline que contiene una o más etapas, y este pipeline transforma los documentos en un resultado agregado.
Tip
Tutoriales completos sobre agregación
Puedes encontrar tutoriales que proporcionan explicaciones detalladas de tareas de agregación comunes en el Tutoriales completos del pipeline de agregación en el manual del servidor. Selecciona un tutorial y luego elige PHP en el menú desplegable Select your language en la esquina superior derecha de la página.
Analogía
Una operación de agregación se asemeja a una fábrica de automóviles. Una fábrica de automóviles tiene una línea de ensamblaje, que contiene estaciones de ensamblaje con herramientas especializadas para realizar tareas específicas, como taladros y soldadores. Las piezas en bruto ingresan a la fábrica y luego la línea de montaje las transforma y ensambla en un producto terminado.
La pipeline de agregación es la cadena de ensamblaje, las etapas de agregación son las estaciones de ensamblaje y las expresiones de operadores son las herramientas especializadas.
Comparar las operaciones de agregación y búsqueda
Se pueden utilizar las operaciones de búsqueda para realizar las siguientes acciones:
Seleccione qué documentos devolver
Seleccione qué campos devolver
Ordenar los resultados
Puedes utilizar operaciones de agregación para realizar las siguientes acciones:
Ejecutar operaciones de búsqueda
Renombrar campos
Calcular campos
Resumir datos
Agrupar valores
Limitaciones
Considera las siguientes limitaciones al realizar operaciones de agregación:
Los documentos devueltos no pueden violar el límite de tamaño de documento BSON de 16 megabytes.
Las etapas del pipeline tienen un límite de memoria de 100 megabytes por defecto. Puedes superar este límite creando un arreglo de opciones que establezca el
allowDiskUseopción atruey pasar el arreglo al métodoMongoDB\Collection::aggregate().Importante
Excepción $graphLookup
La etapa $graphLookup tiene un límite estricto de memoria de 100 megabytes e ignora la opción
allowDiskUse.
APIs de agregación
La librería PHP proporciona las siguientes API para crear pipeline de agregación:
API de arrays: Crea pipelines de agregación pasando arreglos que especifican las etapas de agregación.
Constructor de agregación: crea pipelines de agregación utilizando métodos de fábrica para que tu aplicación sea más segura en cuanto a tipos y más fácil de depurar.
Las siguientes secciones describen cada API y proporcionan ejemplos para crear pipelines de agregación.
Array API
Para realizar una agregación, pasa un arreglo que contenga las etapas del pipeline como documentos BSON al método MongoDB\Collection::aggregate(), como se muestra en el siguiente código:
$pipeline = [ ['<stage>' => <parameters>], ['<stage>' => <parameters>], ... ]; $cursor = $collection->aggregate($pipeline);
Los ejemplos de esta sección utilizan la colección restaurants en la base de datos sample_restaurants de los conjuntos de datos de muestra de Atlas. Para aprender a crear una implementación gratuita de MongoDB y cargar los conjuntos de datos de muestra, consulte la guía Empezando con MongoDB.
Ejemplo de Filtro y Agrupación
El siguiente ejemplo de código produce un recuento del número de panaderías en cada distrito de Nueva York. Para ello, utiliza una pipeline de agregación que contiene las siguientes etapas:
$match etapa para filtrar documentos en los que el campo
cuisinecontenga el valor'Bakery'$group etapa para agrupar los documentos coincidentes por el campo
borough, acumulando un conteo de documentos para cada valor distinto
$pipeline = [ ['$match' => ['cuisine' => 'Bakery']], ['$group' => ['_id' => '$borough', 'count' => ['$sum' => 1]]], ]; $cursor = $collection->aggregate($pipeline); foreach ($cursor as $doc) { echo json_encode($doc), PHP_EOL; }
{"_id":"Brooklyn","count":173} {"_id":"Queens","count":204} {"_id":"Bronx","count":71} {"_id":"Staten Island","count":20} {"_id":"Missing","count":2} {"_id":"Manhattan","count":221}
Explica una agregación
Para ver información sobre cómo MongoDB ejecuta tu operación, puedes instruir al planificador de consultas de MongoDB para que la explique. Cuando MongoDB explica una operación, devuelve planes de ejecución y estadísticas de rendimiento. Un plan de ejecución es una forma potencial en la que MongoDB puede completar una operación. Cuando instruyes a MongoDB para que explique una operación, devuelve tanto el plan que MongoDB ejecutó como cualquier plan de ejecución rechazado.
Para explicar una operación de agregación, construye un objeto MongoDB\Operation\Aggregate y pasa la base de datos, la colección y las etapas del pipeline como parámetros. Luego, pasa el objeto MongoDB\Operation\Aggregate al método MongoDB\Collection::explain().
El siguiente ejemplo le indica a MongoDB que explique la operación de agregación de la sección anterior:
$pipeline = [ ['$match' => ['cuisine' => 'Bakery']], ['$group' => ['_id' => '$borough', 'count' => ['$sum' => 1]]], ]; $aggregate = new MongoDB\Operation\Aggregate( $collection->getDatabaseName(), $collection->getCollectionName(), $pipeline, ); $result = $collection->explain($aggregate); echo json_encode($result), PHP_EOL;
{"explainVersion":"2","queryPlanner":{"namespace":"sample_restaurants.restaurants", "indexFilterSet":false,"parsedQuery":{"cuisine":{"$eq":"Bakery"}},"queryHash":"865F14C3", "planCacheKey":"D56D6F10","optimizedPipeline":true,"maxIndexedOrSolutionsReached":false, "maxIndexedAndSolutionsReached":false,"maxScansToExplodeReached":false,"winningPlan":{ ... }
Creador de agregaciones
Para crear una pipeline de agregación utilizando el Generador de agregación, realiza las siguientes acciones:
Cree un arreglo para almacenar las etapas de la pipeline.
Para cada etapa, llama al método de fábrica del
Stageque comparte el mismo nombre que la etapa de agregación deseada. Por ejemplo, para crear una etapa$unwind, llama al métodoStage::unwind().Dentro del cuerpo del método
Stage, utiliza métodos de otras clases del generador, comoQuery,ExpressionoAccumulator, para expresar tus especificaciones de agregación.
El código a continuación demuestra la plantilla para construir pipelines de agregación:
$pipeline = [ Stage::<factory method>( <stage specification> ), Stage::<factory method>( <stage specification> ), ... ]; $cursor = $collection->aggregate($pipeline);
Los ejemplos en esta sección están adaptados del manual del servidor MongoDB. Cada ejemplo proporciona un enlace a los datos de muestra que puede insertar en su base de datos para probar la operación de agregación.
Tip
Operaciones con desarrolladores
Puedes usar objetos builder para admitir operaciones que no sean de agregación, como operaciones de búsqueda y actualización. Para obtener más información, consulta la Guía de Operaciones con desarrolladores.
Ejemplo de Filtro y Agrupación
Este ejemplo utiliza los datos de muestra proporcionados en la sección Calcular recuento, suma y promedio de la referencia de etapa $group en el manual del servidor.
El siguiente ejemplo de código calcula el monto total de ventas, la cantidad promedio de ventas y el recuento de ventas para cada día del año 2014. Para ello, utiliza una pipeline de agregación que contiene las siguientes etapas:
$match etapa para filtrar documentos que tengan un campo
dateen el que el año sea 2014$group etapa para agrupar los documentos por fecha y calcular el monto total de las ventas, la cantidad media de ventas y el recuento de ventas para cada grupo
$sort etapa para ordenar los resultados por el monto total de venta de cada grupo en orden descendente
$pipeline = [ MongoDB\Builder\Stage::match( date: [ MongoDB\Builder\Query::gte(new MongoDB\BSON\UTCDateTime(new DateTimeImmutable('2014-01-01'))), MongoDB\Builder\Query::lt(new MongoDB\BSON\UTCDateTime(new DateTimeImmutable('2015-01-01'))), ], ), MongoDB\Builder\Stage::group( _id: MongoDB\Builder\Expression::dateToString(MongoDB\Builder\Expression::dateFieldPath('date'), '%Y-%m-%d'), totalSaleAmount: MongoDB\Builder\Accumulator::sum( MongoDB\Builder\Expression::multiply( MongoDB\Builder\Expression::numberFieldPath('price'), MongoDB\Builder\Expression::numberFieldPath('quantity'), ), ), averageQuantity: MongoDB\Builder\Accumulator::avg( MongoDB\Builder\Expression::numberFieldPath('quantity'), ), count: MongoDB\Builder\Accumulator::sum(1), ), MongoDB\Builder\Stage::sort( totalSaleAmount: MongoDB\Builder\Type\Sort::Desc, ), ]; $cursor = $collection->aggregate($pipeline); foreach ($cursor as $doc) { echo json_encode($doc), PHP_EOL; }
{"_id":"2014-04-04","totalSaleAmount":{"$numberDecimal":"200"},"averageQuantity":15,"count":2} {"_id":"2014-03-15","totalSaleAmount":{"$numberDecimal":"50"},"averageQuantity":10,"count":1} {"_id":"2014-03-01","totalSaleAmount":{"$numberDecimal":"40"},"averageQuantity":1.5,"count":2}
Ejemplo para desanidar arrays embebidos
En este ejemplo se utilizan los datos de muestra proporcionados en la sección Desenrollar Arreglos Integrados de la referencia de etapas $unwind en el Manual del Servidor.
El siguiente ejemplo de código agrupa los artículos vendidos por sus etiquetas y calcula el importe total de ventas para cada etiqueta. Para ello, utiliza una pipeline de agregación que contiene las siguientes etapas:
$unwind etapa para emitir un documento separado para cada elemento en el arreglo
itemsLa etapa $unwind para generar un documento independiente para cada elemento en los arreglos
items.tags.$group etapa para agrupar los documentos por el valor de la etiqueta y calcular el monto total de ventas de los artículos que tienen cada etiqueta
$pipeline = [ MongoDB\Builder\Stage::unwind(MongoDB\Builder\Expression::arrayFieldPath('items')), MongoDB\Builder\Stage::unwind(MongoDB\Builder\Expression::arrayFieldPath('items.tags')), MongoDB\Builder\Stage::group( _id: MongoDB\Builder\Expression::fieldPath('items.tags'), totalSalesAmount: MongoDB\Builder\Accumulator::sum( MongoDB\Builder\Expression::multiply( MongoDB\Builder\Expression::numberFieldPath('items.price'), MongoDB\Builder\Expression::numberFieldPath('items.quantity'), ), ), ), ]; $cursor = $collection->aggregate($pipeline); foreach ($cursor as $doc) { echo json_encode($doc), PHP_EOL; }
{"_id":"office","totalSalesAmount":{"$numberDecimal":"1019.60"}} {"_id":"school","totalSalesAmount":{"$numberDecimal":"104.85"}} {"_id":"stationary","totalSalesAmount":{"$numberDecimal":"264.45"}} {"_id":"electronics","totalSalesAmount":{"$numberDecimal":"800.00"}} {"_id":"writing","totalSalesAmount":{"$numberDecimal":"60.00"}}
Ejemplo de unión de igualdad simple
Este ejemplo utiliza los datos de muestra proporcionados en la sección Realizar una única combinación de igualdad con $lookup de la referencia de la etapa $lookup en el manual del servidor.
El siguiente ejemplo de código une los documentos de la colección orders con los documentos de la colección inventory usando el campo item de la colección orders y el campo sku de la colección inventory.
Para ello, el ejemplo utiliza una pipeline de agregación que contiene una etapa $lookup que especifica la colección de la que se recuperarán los datos y los nombres de los campos locales y externos.
$pipeline = [ MongoDB\Builder\Stage::lookup( from: 'inventory', localField: 'item', foreignField: 'sku', as: 'inventory_docs', ), ]; /* Performs the aggregation on the orders collection */ $cursor = $collection->aggregate($pipeline); foreach ($cursor as $doc) { echo json_encode($doc), PHP_EOL; }
{"_id":1,"item":"almonds","price":12,"quantity":2,"inventory_docs":[{"_id":1,"sku":"almonds","description":"product 1","instock":120}]} {"_id":2,"item":"pecans","price":20,"quantity":1,"inventory_docs":[{"_id":4,"sku":"pecans","description":"product 4","instock":70}]} {"_id":3,"inventory_docs":[{"_id":5,"sku":null,"description":"Incomplete"},{"_id":6}]}
Información Adicional
Para ver un tutorial que utiliza la Librería PHP de MongoDB para crear pipelines de agregación complejos, consulta Mejor soporte para pipelines de agregación en el Controlador PHP de MongoDB en el sitio web de DEV Community.
Para ver más ejemplos de pipelines de agregación construidos utilizando el Creador de Agregaciones, consulta la suite de pruebas de la clase Stage en el código fuente de la biblioteca PHP en GitHub.
Manual del Servidor de MongoDB
Para aprender más sobre los temas tratados en esta guía, consulta las siguientes páginas del manual del servidor MongoDB:
Para obtener una lista completa de las etapas de agregación, consulta Etapas de agregación en el manual de MongoDB Server.
Para aprender sobre cómo armar un pipeline de agregación y para ver ejemplos, consulta pipeline de agregación.
Para obtener más información sobre cómo crear etapas de pipeline, consulta Etapas de agregación.
Para obtener más información sobre cómo explicar las operaciones de MongoDB, consulta Resultado de explicación y Planes de consultas.
MongoDB Search y búsqueda vectorial
Puedes realizar búsquedas de texto completo utilizando la funcionalidad de búsqueda de MongoDB. Para obtener más información, consulta la guía sobre cómo ejecutar una MongoDB Search query.
Puedes realizar búsquedas de similitud en incrustaciones vectoriales mediante el uso de la funcionalidad de MongoDB Vector Search. Para obtener más información, consulta la Guía para ejecutar una MongoDB Vector Search query.
Documentación de la API
Para obtener más información sobre los métodos discutidos en esta guía, consulta la siguiente documentación de la API: