Docs Menu
Docs Home
/ /

Operaciones de agregación

En esta guía, puede aprender a utilizar la biblioteca PHP MongoDB para realizar operaciones de agregación.

Las operaciones de agregación procesan los datos de sus colecciones de MongoDB y devuelven resultados calculados. El marco de agregación de MongoDB, que forma parte de la API de consultas, se basa en el concepto de canalizaciones de procesamiento de datos. Los documentos entran en una canalización que contiene una o más etapas, y esta canalización los transforma en un resultado agregado.

Tip

Tutoriales completos sobre agregación

Puede encontrar tutoriales que brindan explicaciones detalladas de tareas de agregación comunes en Sección completa de tutoriales decanalización de agregación del manual del servidor. Seleccione un tutorial y luego seleccione PHP desde el menú desplegable Select your language en la esquina superior derecha de la página.

Una operación de agregación es similar a una fábrica de automóviles. Una fábrica de automóviles cuenta con 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 entran en la fábrica y luego la línea de ensamblaje las transforma y ensambla en un producto terminado.

La tubería de agregación es la línea de ensamblaje, las etapas de agregación son las estaciones de ensamblaje y las expresiones del operador son las herramientas especializadas.

Se pueden utilizar las operaciones de búsqueda para realizar las siguientes acciones:

  • Seleccione qué documentos desea devolver

  • Seleccione qué campos desea devolver

  • Ordenar los resultados

Puede utilizar operaciones de agregación para realizar las siguientes acciones:

  • Ejecutar operaciones de búsqueda

  • Cambiar el nombre de los campos

  • Calcular campos

  • Resumir datos

  • Valores del grupo

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 de la canalización tienen un límite de memoria de 100 megabytes por defecto. Puedes superar este límite creando una matriz de opciones que establezca allowDiskUse opción a true y pasando la matriz al método MongoDB\Collection::aggregate().

    Importante

    Excepción $graphLookup

    La etapa $graphLookup tiene un límite de memoria estricto de 100 megabytes e ignora la allowDiskUse opción.

La biblioteca PHP proporciona las siguientes API para crear canales de agregación:

  • API de matriz: crea canales de agregación pasando matrices que especifican las etapas de agregación.

  • Generador de agregaciones: cree canales de agregación mediante métodos de fábrica para que su aplicación sea más segura y depurable.

Las siguientes secciones describen cada API y proporcionan ejemplos para crear canales de agregación.

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 restaurants colección de la base de datos de los sample_restaurants conjuntos de datos de ejemplo de Atlas. Para aprender a crear una implementación gratuita de MongoDB y cargar los conjuntos de datos de ejemplo, consulte la guía de introducción a MongoDB.

El siguiente ejemplo de código genera un recuento del número de panaderías en cada distrito de Nueva York. Para ello, utiliza una canalización de agregación que consta de las siguientes etapas:

  1. Etapa$match para filtrar los documentos en los que el cuisine campo contiene el valor 'Bakery'

  2. Etapa de grupo para agrupar los documentos coincidentes por el borough campo, acumulando un recuento 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}

Para ver información sobre cómo MongoDB ejecuta su operación, puede indicarle al planificador de consultas de MongoDB 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 en que MongoDB puede completar una operación. Al indicarle a MongoDB que explique una operación, devuelve tanto el plan ejecutado como cualquier plan de ejecución rechazado.

Para explicar una operación de agregación, construya un objeto MongoDB\Operation\Aggregate y pase las etapas de base de datos, colección y canalización como parámetros. Luego, pase 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":{
... }

Para crear una canalización de agregación mediante el Generador de agregaciones, realice las siguientes acciones:

  1. Cree una instancia MongoDB\Builder\Pipeline para almacenar las etapas de la canalización.

  2. Para cada etapa, llama al método de fábrica del Stage que comparte el mismo nombre que la etapa de agregación deseada. Por ejemplo, para crear una etapa $unwind, llama al método Stage::unwind().

  3. Dentro del cuerpo del método Stage, utilice métodos de otras clases de generador como Query, Expression o Accumulator para expresar sus especificaciones de agregación.

El siguiente código demuestra la plantilla para construir canalizaciones de agregación:

$pipeline = new Pipeline(
Stage::<factory method>(
<stage specification>
),
Stage::<factory method>(
<stage specification>
),
// ...
);
$cursor = $collection->aggregate($pipeline);

Los ejemplos de esta sección están adaptados del manual de MongoDB Server. Cada ejemplo proporciona un enlace a los datos de muestra que puede insertar en su base de datos para probar la agregación.

Tip

Operaciones con Constructores

Puede usar constructores para admitir operaciones que no sean de agregación, como las de búsqueda y actualización. Para obtener más información, consulte Guía deoperaciones con constructores.

Este ejemplo utiliza los datos de muestra proporcionados en la sección Calcular recuento, suma y promedio de la referencia de la $group etapa en el manual del servidor.

El siguiente ejemplo de código calcula el importe 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 canalización de agregación que consta de las siguientes etapas:

  1. Etapa $match para filtrar documentos que contienen un date campo en el que el año es 2014

  2. Etapa de grupo para agrupar los documentos por fecha y calcular el monto total de ventas, la cantidad promedio de ventas y el recuento de ventas para cada grupo

  3. Etapa $sort para ordenar los resultados por el monto total de venta para cada grupo en orden descendente

$pipeline = new MongoDB\Builder\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}

Este ejemplo utiliza los datos de muestra proporcionados en la sección Unwind Embedded Arrays de la $unwind referencia de la etapa 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 canalización de agregación que consta de las siguientes etapas:

  1. Etapa$unwind para generar un documento separado para cada elemento en la items matriz

  2. Etapa$unwind para generar un documento separado para cada elemento en las items.tags matrices

  3. Etapa de grupo para agrupar los documentos por valor de etiqueta y calcular el monto total de ventas de los artículos que tienen cada etiqueta

$pipeline = new MongoDB\Builder\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"}}

Este ejemplo utiliza los datos de muestra proporcionados en la sección Realizar una unión de igualdad única con $lookup de la referencia de la $lookup etapa 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 canalización 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 = new MongoDB\Builder\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}]}

Para ver un tutorial que utiliza la biblioteca PHP de MongoDB para crear canales de agregación complejos, consulte Canalizaciones de agregación complejas con PHP básico y MongoDB en el Centro para desarrolladores de MongoDB.

Para ver más ejemplos de canalizaciones de agregación creadas mediante el Generador de agregación, consulte el conjunto de pruebas de la clase Stage en el código fuente de la biblioteca PHP en GitHub.

Para obtener más información sobre los temas tratados en esta guía, consulte las siguientes páginas del manual de MongoDB Server:

  • Para obtener una lista completa de las etapas de agregación, consulta Etapas de agregación en el manual de MongoDB Server.

  • Para obtener más información sobre cómo ensamblar una canalización de agregación y ver ejemplos, consulte Canalización de agregación.

  • Para obtener más información sobre cómo crear etapas de canalización, consulte Etapas de agregación.

  • Para obtener más información sobre cómo explicar las operaciones de MongoDB, consulte Explicar los planesde salida y consulta.

Puede realizar búsquedas de texto completo con la función de búsqueda de MongoDB. Para obtener más información, consulte la guía "Ejecutar una consulta de búsqueda de MongoDB".

Puede realizar búsquedas de similitud en incrustaciones vectoriales mediante la función de búsqueda vectorial de MongoDB. Para obtener más información, consulte la guía "Ejecutar una consulta de búsqueda vectorial de MongoDB".

Para obtener más información sobre los métodos analizados en esta guía, consulte la siguiente documentación de API:

Volver

Operaciones con Constructores

En esta página