Overview
En esta guía, aprenderá a utilizar la clase Aggregates, que proporciona métodos de fábrica estáticos para construir las etapas de la canalización de agregación en el controlador Java Reactive Streams.
Para una introducción más completa a la agregación, consulte la guía de agregación.
Los ejemplos en esta página asumen importaciones para los métodos de las siguientes clases:
AggregatesFiltersProjectionsSortsAccumulators
El siguiente código muestra cómo importar los métodos de las clases anteriores:
import static java.util.Arrays.asList; import static com.mongodb.client.model.Accumulators.*; import static com.mongodb.client.model.Aggregates.*; import static com.mongodb.client.model.Filters.*; import static com.mongodb.client.model.Projections.*; import static com.mongodb.client.model.Sorts.*; import static com.mongodb.client.model.search.SearchPath.fieldPath;
Usa estos métodos para construir etapas del pipeline y especificarlas en tu agregación como una lista:
Bson matchStage = match(eq("some_field", "some_criteria")); Bson sortByCountStage = sortByCount("some_field"); Publisher<Document> results = collection.aggregate(asList(matchStage, sortByCountStage)); Flux.from(results).collectList().block();
coincidencia
Utilice el match() método para crear una etapa de canalización $match que compare los documentos entrantes con el filtro de consulta especificado, descartando los documentos que no coincidan. Puede construir el filtro utilizando la clase Filters o cualquier otra Bson instancia de.
El siguiente ejemplo crea una etapa de pipeline que coincide con todos los documentos donde el campo title es igual a "The Shawshank Redemption":
match(eq("title", "The Shawshank Redemption"));
Proyecto
Utilice el project() método para crear una etapa de canalización $project que proyecte campos de documento específicos. La proyección de campos en la agregación sigue las mismas reglas que la proyección de campos en las consultas. Puede construir la proyección utilizando la clase Projections o cualquier otra Bson instancia de.
El siguiente ejemplo crea una etapa de pipeline que excluye el campo _id pero incluye los campos title y plot:
project(fields(include("title", "plot"), excludeId()));
Proyección de campos calculados
La etapa $project puede generar campos existentes o campos calculados.
El siguiente ejemplo crea una etapa de pipeline que proyecta el campo rated en un nuevo campo llamado rating, renombrando efectivamente el campo.
project(fields(computed("rating", "$rated"), excludeId()));
Documentos
Usa el método documents() para crear una etapa de pipeline $documents que devuelva documentos literales a partir de valores de entrada.
Importante
Si utiliza una etapa $documents en una pipeline de agregación, debe ser la primera etapa de la pipeline.
El siguiente ejemplo crea una etapa de pipeline que crea documentos de muestra con un campo title:
documents(asList( new Document("title", "The Shawshank Redemption"), new Document("title", "Back to the Future"), new Document("title", "Jurassic Park")));
Importante
Si utiliza el método documents() para proporcionar la entrada a una canalización de agregación, debe llamar al método aggregate() en una base de datos en lugar de en una colección.
muestra
Utilice el método sample() para crear una etapa de pipeline $sample para seleccionar al azar documentos de entrada.
El siguiente ejemplo crea una etapa de la pipeline que selecciona aleatoriamente 5 documentos:
sample(5);
Sort
Utilice el sort() método para crear una etapa de canalización $sort para ordenar según los criterios especificados. Puede construir los criterios de ordenación utilizando la clase Sorts o cualquier otra Bson instancia de.
El siguiente ejemplo crea una etapa de canalización que ordena en orden descendente según el valor del campo year:
sort(orderBy(descending("year"), ascending("title")));
Omitir
Utiliza el método skip() para crear una etapa de pipeline de $skip para omitir la cantidad específica de documentos antes de pasar los documentos a la siguiente etapa.
El siguiente ejemplo crea una etapa de pipeline que omite los primeros 5 documentos:
skip(5);
Limit
Utiliza la etapa de la $limit pipeline para limitar el número de documentos que se pasan a la siguiente etapa.
El siguiente ejemplo crea una etapa de pipeline que limita el número de documentos a 10:
limit(10);
Consulta
Utiliza el método lookup() para crear una etapa en la pipeline $lookup y realizar combinaciones y subconsultas no correlacionadas entre dos colecciones.
Left Outer Join
El siguiente ejemplo crea una etapa de pipeline que realiza una unión externa izquierda entre las colecciones movies y comments:
Une el campo
_iddemoviescon el campomovie_idencommentsMuestra los resultados en el campo
joined_comments:
lookup("comments", "_id", "movie_id", "joined_comments");
Full Join y subconsultas no correlacionadas
El siguiente ejemplo crea una etapa de canalización que realiza una auto-unión en la colección movies para encontrar películas que comparten un género con cada película y tienen un imdb.rating más alto:
List<Variable<Object>> variables = asList( new Variable<>("genre", new Document("$arrayElemAt", asList("$genres", 0))), new Variable<>("rating", "$imdb.rating") ); List<Bson> pipeline = asList( match(expr(new Document("$and", asList( new Document("$in", asList("$$genre", "$genres")), new Document("$gt", asList("$imdb.rating", "$$rating")) )))), project(fields(include("title", "imdb.rating"), excludeId()))); Bson similarHigherRatedLookup = lookup("movies", variables, pipeline, "similar_higher_rated");
group
Usa el método group() para crear una etapa de pipeline de $group para agrupar documentos por una expresión especificada y producir un documento por cada agrupación distinta.
Tip
El controlador incluye la clase Acumuladores con métodos de fábrica estáticos para cada uno de los acumuladores soportados.
El siguiente ejemplo crea una etapa de pipeline que agrupa los documentos por el valor del campo customerId. Cada grupo acumula la suma y el promedio de los valores del campo quantity en los campos totalQuantity y averageQuantity.
group("$customerId", sum("totalQuantity", "$quantity"), avg("averageQuantity", "$quantity"));
Para obtener más información sobre los operadores de acumuladores, consulte la página de Acumuladores en el manual del servidor.
Acumuladores Pick-N
Los acumuladores pick-N son operadores de acumulación de agregación que devuelven los elementos superiores e inferiores dada una ordenación específica. Usa uno de los siguientes desarrolladores para crear un operador de acumulación de agregación:
Tip
Solo puede realizar operaciones de agregación con estos acumuladores pick-n cuando su implementación de MongoDB (incluidos los clústeres de Atlas) esté ejecutando MongoDB Server 5.2 o posterior.
Para saber con qué etapas de la canalización de agregación puede usar operadores acumuladores, consulte la página Acumuladores en el manual del servidor.
MinN
El desarrollador de minN() crea el acumulador $minN que retorna datos de documentos que contienen los n valores más bajos de una agrupación.
Tip
Los acumuladores $minN y $bottomN pueden realizar tareas similares. Consultar Comparación de los acumuladores $minN y $bottomN para su uso recomendado.
El siguiente ejemplo muestra cómo utilizar el método minN() para devolver los tres valores más bajos de imdb.rating de las películas, agrupados por year:
group( "$year", minN( "lowest_three_ratings", new BsonString("$imdb.rating"), 3 ));
Consulta la documentación de la API minN() para obtener más información.
MaxN
El acumulador maxN() devuelve datos de los documentos que contienen los n valores más altos de un agrupamiento.
El siguiente ejemplo demuestra cómo usar el método maxN() para devolver los dos valores más altos de imdb.rating de películas, agrupados por year:
group( "$year", maxN( "highest_two_ratings", new BsonString("$imdb.rating"), 2 ));
Consulta la documentación de la API maxN() para obtener más información.
FirstN
El acumulador firstN() devuelve los datos de los primeros n documentos en cada agrupación para el orden de clasificación especificado.
Tip
Los acumuladores $firstN y $topN pueden realizar tareas similares. Consulta Comparación de los acumuladores $firstN y $topN para el uso recomendado de cada uno.
El siguiente ejemplo demuestra cómo utilizar el método firstN() para devolver los primeros cuatro valores de title de películas, sobre la base del orden en que llegaron al escenario, agrupados por year:
group( "$year", firstN( "first_four_movies", new BsonString("$title"), 4 ));
Consulte la documentación de la API firstN() para más información.
LastN
El acumulador lastN() devuelve datos de los últimos n documentos en cada agrupación para el orden de clasificación especificado.
El siguiente ejemplo demuestra cómo usar el método lastN() para mostrar los últimos tres valores de la película title, según el orden en que aparecieron en escena, agrupados por year:
group( "$year", lastN( "last_three_movies", new BsonString("$title"), 3 ));
Consulta la documentación de lastN() API para más información.
top
El acumulador top() devuelve datos del primer documento de un grupo según el orden de clasificación especificado.
El siguiente ejemplo demuestra cómo utilizar el método top() para devolver los valores title y imdb.rating de las películas mejor valoradas según el imdb.rating, agrupadas por year.
group( "$year", top( "top_rated_movie", descending("imdb.rating"), asList(new BsonString("$title"), new BsonString("$imdb.rating")) ));
Consulta la documentación de la API top() para obtener más información.
TopN
El acumulador topN() devuelve datos de documentos que contienen los valores más altos de n para el campo especificado.
Tip
Los acumuladores $firstN y $topN pueden realizar tareas similares. Consulta Comparación de los acumuladores $firstN y $topN para el uso recomendado de cada uno.
El siguiente ejemplo demuestra cómo utilizar el método topN() para devolver los valores title y runtime de las tres películas más largas basadas en los valores runtime, agrupados por year.
group( "$year", topN( "longest_three_movies", descending("runtime"), asList(new BsonString("$title"), new BsonString("$runtime")), 3 ));
Consulte la documentación de la API topN() para obtener más información.
Fondo
El acumulador bottom() devuelve datos del último documento en un grupo según el orden de clasificación especificado.
El siguiente ejemplo demuestra cómo usar el método bottom() para devolver los valores title y runtime de la película más corta en función del valor runtime, agrupados por year.
group( "$year", bottom( "shortest_movies", descending("runtime"), asList(new BsonString("$title"), new BsonString("$runtime")) ));
Consulta la documentación de la API bottom() para obtener más información.
NInferior
El acumulador bottomN() devuelve datos de documentos que contienen los valores n más bajos para el campo especificado.
Tip
Los acumuladores $minN y $bottomN pueden realizar tareas similares. Consultar Comparación de los acumuladores $minN y $bottomN para su uso recomendado.
El siguiente ejemplo demuestra cómo utilizar el método bottomN() para devolver los valores title y imdb.rating de las dos películas con la calificación más baja según el valor imdb.rating, agrupadas por year:
group( "$year", bottomN( "lowest_rated_two_movies", descending("imdb.rating"), asList(new BsonString("$title"), new BsonString("$imdb.rating")), 2 ));
Consulta la documentación de la API bottomN() para obtener más información.
Unwind
Utiliza el método unwind() para crear una etapa de pipeline $unwind para descomponer un campo de arreglo de documentos de entrada, creando un documento de salida por cada elemento del arreglo.
El siguiente ejemplo crea un documento para cada elemento del arreglo sizes:
unwind("$sizes");
El siguiente ejemplo conserva los documentos que tienen valores faltantes o null para el campo de matriz, o donde la matriz está vacía:
unwind("$sizes", new UnwindOptions().preserveNullAndEmptyArrays(true));
El siguiente ejemplo incluye el índice de la matriz en un campo llamado "position":
unwind("$sizes", new UnwindOptions().includeArrayIndex("position"));
Fuera
Utilice el método out() para crear una etapa de pipeline $out que escriba todos los documentos en la colección especificada, en la misma base de datos.
Importante
La etapa $out debe ser la última etapa de cualquier pipeline de agregación.
El siguiente ejemplo guarda los resultados de la pipeline en la colección authors:
out("authors");
Unir
Use el método merge() para crear una etapa del pipeline $merge que fusione todos los documentos en la colección especificada.
Importante
La etapa $merge debe ser la última etapa de cualquier pipeline de agregación.
El siguiente ejemplo fusiona el pipeline en la colección authors utilizando las opciones por defecto:
merge("authors");
El siguiente ejemplo fusiona la pipeline en la colección customers de la base de datos reporting utilizando algunas opciones que especifican reemplazar el documento si tanto date como customerId coinciden, de lo contrario inserta el documento:
merge(new MongoNamespace("reporting", "customers"), new MergeOptions().uniqueIdentifier(asList("date", "customerId")) .whenMatched(MergeOptions.WhenMatched.REPLACE) .whenNotMatched(MergeOptions.WhenNotMatched.INSERT));
GraphLookup
Utiliza el método graphLookup() para crear una etapa en la pipeline de $graphLookup que realice una búsqueda recursiva en una colección especificada para hacer coincidir un campo especificado en un documento con un campo especificado de otro documento.
El siguiente ejemplo calcula el grafo de la red social para los usuarios de la colección contacts, emparejando recursivamente el valor en el campo friends con el campo name:
graphLookup("contacts", "$friends", "friends", "name", "socialNetwork");
Usando GraphLookupOptions, puedes especificar la profundidad a la que recursar, así como el nombre del campo de profundidad, si lo deseas. En este ejemplo, $graphLookup realizará recursión hasta dos veces y creará un campo llamado degrees con la información sobre la profundidad de recursión para cada documento.
graphLookup("contacts", "$friends", "friends", "name", "socialNetwork", new GraphLookupOptions().maxDepth(2).depthField("degrees"));
Con GraphLookupOptions, puedes especificar un filtro que los documentos deben cumplir para que MongoDB los incluya en tu búsqueda. En este ejemplo, solo se incluirán los enlaces que contengan 'golf' en su campo hobbies.
graphLookup("contacts", "$friends", "friends", "name", "socialNetwork", new GraphLookupOptions().maxDepth(1).restrictSearchWithMatch(eq("hobbies", "golf")));
SortByCount
Utiliza el método sortByCount() para crear una etapa de pipeline $sortByCount que agrupa los documentos por una expresión dada y luego ordena estos grupos por cantidad en orden descendente.
Tip
La etapa $sortByCount es idéntica a una etapa $group con un acumulador $sum seguido de una etapa $sort.
[ { "$group": { "_id": <expression to group on>, "count": { "$sum": 1 } } }, { "$sort": { "count": -1 } } ]
El siguiente ejemplo agrupa los documentos por el valor truncado del campo x y calcula el recuento para cada valor distinto:
sortByCount(new Document("$floor", "$x"));
ReplaceRoot
Usa el método replaceRoot() para crear una $replaceRoot etapa de pipeline que reemplace cada documento de entrada por el documento especificado.
El siguiente ejemplo reemplaza cada documento de entrada con el documento anidado en el campo spanish_translation:
replaceRoot("$spanish_translation");
AddFields
Utiliza el método addFields() para crear una etapa de pipeline $addFields que agregue nuevos campos a los documentos.
Tip
Utiliza $addFields cuando no se requiera proyectar la inclusión o exclusión de campos.
El siguiente ejemplo agrega dos nuevos campos, a y b, a los documentos de entrada:
addFields(new Field("a", 1), new Field("b", 2));
count
Utilice el count() método para crear una etapa de canalización $count que cuente el número de documentos que ingresan a la etapa y asigne ese valor a un nombre de campo específico. Si no especifica un nombre de campo, asigna por defecto count() el nombre de campo "count".
Tip
La etapa $count es equivalente a la siguiente etapa de mongosh:
{ "$group":{ "_id": 0, "count": { "$sum" : 1 } } }
El siguiente ejemplo crea una etapa del pipeline que muestra la cantidad de documentos entrantes en un campo llamado "total":
count("total");
Balde
Utiliza el método bucket() para crear una etapa de pipeline $bucket que automatiza la agrupación de datos en torno a valores límite predefinidos.
El siguiente ejemplo crea una etapa de pipeline que agrupa los documentos entrantes según el valor de su campo screenSize, incluyendo el límite inferior y excluyendo el límite superior.
bucket("$screenSize", asList(0, 24, 32, 50, 70, 200));
Utiliza la clase BucketOptions para especificar un bucket por defecto para los valores que se encuentren fuera de los límites especificados, y para indicar acumuladores adicionales.
El siguiente ejemplo crea una etapa de pipeline que agrupa los documentos entrantes según el valor de su campo screenSize, contando el número de documentos que caen en cada segmento, introduciendo el valor de screenSize en un campo llamado matches y capturando cualquier tamaño de pantalla superior a "70" en un segmento llamado "monstruo" para tamaños de pantalla monstruosamente grandes:
Tip
El controlador incluye la clase Acumuladores con métodos de fábrica estáticos para cada uno de los acumuladores soportados.
bucket("$screenSize", asList(0, 24, 32, 50, 70), new BucketOptions().defaultBucket("monster").output(sum("count", 1), push("matches", "$screenSize")));
BucketAuto
Usa el bucketAuto() método para crear una $bucketAuto etapa de la pipeline que determina automáticamente los límites de cada bucket intentando distribuir equitativamente los documentos en una cantidad especificada de buckets.
El siguiente ejemplo crea una etapa de canalización que intentará crear y distribuir uniformemente documentos en 10 cubetas utilizando el valor de su campo price:
bucketAuto("$price", 10);
Utiliza la clase BucketAutoOptions para especificar un esquema basado en número preferido número preferido para establecer los valores límite, y especifica acumuladores adicionales.
El siguiente ejemplo crea una etapa de canalización que intentará crear y distribuir uniformemente documentos en 10 cubetas utilizando el valor de su campo price, estableciendo los límites de las cubetas en potencias de 2 (2, 4, 8, 16, ...). También cuenta el número de documentos en cada cubeta y calcula su promedio price en un nuevo campo llamado avgPrice:
Tip
El controlador incluye la clase Acumuladores con métodos de fábrica estáticos para cada uno de los acumuladores soportados.
bucketAuto("$price", 10, new BucketAutoOptions().granularity(BucketGranularity.POWERSOF2) .output(sum("count", 1), avg("avgPrice", "$price")));
Facet
Utiliza el método facet() para crear una etapa de pipeline $facet que permita la definición de pipelines paralelas.
El siguiente ejemplo crea una etapa del pipeline que ejecuta dos agregaciones en paralelo:
La primera agregación distribuye los documentos entrantes en 5 grupos según su campo
attributes.screen_size.La segunda agregación cuenta todos los fabricantes y devuelve su recuento, limitado a los 5 principales.
facet(new Facet("Screen Sizes", bucketAuto("$attributes.screen_size", 5, new BucketAutoOptions().output(sum("count", 1)))), new Facet("Manufacturer", sortByCount("$attributes.manufacturer"), limit(5)));
SetWindowFields
Utilice el método setWindowFields() para crear una etapa de pipeline $setWindowFields que permita utilizar operadores de ventana para realizar operaciones en un intervalo específico de documentos en una colección.
Tip
Funciones de ventana
El driver incluye la clase Windows con métodos de fábrica estáticos para crear cálculos en ventana.
El siguiente ejemplo crea una etapa de pipeline que calcula la precipitación acumulada y la temperatura media durante el último mes para cada localidad a partir de mediciones más detalladas presentadas en los campos rainfall y temperature:
Window pastMonth = Windows.timeRange(-1, MongoTimeUnit.MONTH, Windows.Bound.CURRENT); setWindowFields("$localityId", ascending("measurementDateTime"), WindowOutputFields.sum("monthlyRainfall", "$rainfall", pastMonth), WindowOutputFields.avg("monthlyAvgTemp", "$temperature", pastMonth));
Densify
Utiliza el método densify() para crear una etapa de pipeline $densify que genere una secuencia de documentos para cubrir un intervalo especificado.
Tip
La etapa de agregación $densify requiere MongoDB Server v5.1 o posterior.
Considera los siguientes documentos recuperados del Conjunto de datos meteorológicos de muestra de Atlas que contienen mediciones para un campo similar de position, espaciadas una hora entre sí:
Document{{ _id=5553a..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:00:00 EST 1984, ... }} Document{{ _id=5553b..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 09:00:00 EST 1984, ... }}
Supón que necesitas crear una etapa de la pipeline que realice las siguientes acciones en estos documentos:
Agrega un documento en cada intervalo de 15 minutos para el cual aún no exista un valor de
ts.Agrupa los documentos por el campo
position.
La llamada al constructor de etapas de agregación densify() que lleva a cabo estas acciones se asemeja a la siguiente:
densify( "ts", DensifyRange.partitionRangeWithStep(15, MongoTimeUnit.MINUTE), DensifyOptions.densifyOptions().partitionByFields("position.coordinates"));
La siguiente salida resalta los documentos generados por la etapa de agregación que contienen valores de ts cada 15 minutos entre los documentos existentes:
Document{{ _id=5553a..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:00:00 EST 1984, ... }} Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:15:00 EST 1984 }} Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:30:00 EST 1984 }} Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:45:00 EST 1984 }} Document{{ _id=5553b..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 09:00:00 EST 1984, ... }}
Consulta la documentación de la API del paquete densify para obtener más información.
Fill
Utilice el método fill() para crear una etapa de pipeline $fill que complete null y los valores de campos faltantes.
Tip
La etapa de agregación $fill requiere MongoDB Server v5.3 o posterior.
Considere los siguientes documentos que contienen mediciones de temperatura y presión atmosférica a un intervalo horario:
Document{{_id=6308a..., hour=1, temperature=23C, air_pressure=29.74}} Document{{_id=6308b..., hour=2, temperature=23.5C}} Document{{_id=6308c..., hour=3, temperature=null, air_pressure=29.76}}
Suponga que necesita completar los puntos de datos de temperatura y presión de aire faltantes en los documentos de la siguiente manera:
Rellene el campo
air_pressurepara la hora "2" utilizando la interpolación lineal para calcular el valor.Establece el valor faltante de
temperatureen "23,6°C". para la hora "3".
La llamada al constructor de etapas de agregación fill() que lleva a cabo estas acciones se asemeja a la siguiente:
fill( FillOptions.fillOptions().sortBy(ascending("hour")), FillOutputField.value("temperature", "23.6C"), FillOutputField.linear("air_pressure") );
La siguiente salida resalta los documentos que contienen campos poblados por la etapa de agregación:
Document{{_id=6308a..., hour=1, temperature=23C, air_pressure=29.74}} Document{{_id=6308b..., hour=2, temperature=23.5C, air_pressure=29.75}} Document{{_id=6308c..., hour=3, temperature=23.6C, air_pressure=29.76}}
Consulte la documentación de la API de fill paquete para más información.
MongoDB búsqueda
Utiliza el método search() para crear una $search etapa de la pipeline que especifique una búsqueda de texto completo en uno o más campos.
Nota
Atlas y requisitos de versión de Community Edition
El operador $search pipeline de agregación está disponible únicamente para colecciones alojadas en clústeres de MongoDB Atlas que ejecutan MongoDB v4.2 o posterior, o en clústeres de MongoDB Community Edition que ejecutan MongoDB v8.2 o posterior. Las colecciones deben estar cubiertas por un índice de búsqueda MongoDB. Para obtener más información sobre la configuración necesaria y la funcionalidad de este operador, consulta la documentación de MongoDB Search.
El siguiente ejemplo crea una etapa de pipeline que busca en el campo title texto que contenga la palabra "Futuro":
Bson textSearch = search( SearchOperator.text( fieldPath("title"), "Future"));
Obtén más información sobre los desarrolladores en la documentación de la API de search paquete.
MongoDB Search metadatos
Utiliza el método searchMeta() para crear una etapa de pipeline $searchMeta que devuelve solo la parte de metadatos de los resultados de las queries de búsqueda en MongoDB Search.
Nota
Atlas y requisitos de versión de Community Edition
Este operador de pipeline de agregación está disponible solo en MongoDB Atlas clústeres que ejecuten la v4.4.11 y posteriores, o en MongoDB Community Edition clústeres con MongoDB v8.2 o posterior. Para obtener una lista detallada de la disponibilidad de las versiones, consulta la documentación de MongoDB Atlas sobre $searchMeta.
El siguiente ejemplo muestra los metadatos count para una etapa de agregación MongoDB Search:
searchMeta( SearchOperator.near(2010, 1, fieldPath("year")));