Overview
En esta guía, puedes aprender cómo utilizar el Agregados clase que proporciona métodos de fábrica estáticos que compilan etapas del pipeline de agregación en el driver de MongoDB Kotlin.
Para una introducción más completa a la agregación, consulte nuestro Guía de agregación.
Los ejemplos de esta página suponen importaciones para métodos de las siguientes clases:
AggregatesFiltersProjectionsSortsAccumulators
import com.mongodb.client.model.Aggregates import com.mongodb.client.model.Filters import com.mongodb.client.model.Projections import com.mongodb.client.model.Sorts import com.mongodb.client.model.Accumulators
Usa estos métodos para construir etapas del pipeline y especificarlas en tu agregación como una lista:
val matchStage = Aggregates.match(Filters.eq("someField", "someCriteria")) val sortByCountStage = Aggregates.sortByCount("\$someField") val results = collection.aggregate( listOf(matchStage, sortByCountStage)).toList()
Muchos Aggregation ejemplos en esta guía utilizan el conjunto de datos Atlas sample_mflix.movies. Los documentos en esta colección están modelados por la siguiente clase de datos Movie para su uso con el controlador de Kotlin:
data class Movie( val title: String, val year: Int, val genres: List<String>, val rated: String, val plot: String, val runtime: Int, val imdb: IMDB, val fullplot: String? = "No full plot", ){ data class IMDB( val rating: Double ) }
Tip
Métodos de construcción y propiedades de la clase de datos
Puedes utilizar los métodos de las clases builder directamente con las propiedades de la data class añadiendo la dependencia opcional de extensiones del driver de Kotlin a tu aplicación. Para obtener más información y ver ejemplos, consulta la guía Utilizar desarrolladores con clases de datos.
coincidencia
Usa el método match() para crear una etapa de pipeline $match que haga coincidir los documentos entrantes con el filtro de query especificado, filtrando los documentos que no coincidan.
Tip
El filtro puede ser una instancia de cualquier clase que implemente Bson, pero es cómodo combinarlo con el uso de la clase Filters. clase.
El siguiente ejemplo crea una etapa del pipeline que coteja todos los documentos en la colección movies donde el campo title es igual a "The Shawshank Redemption":
Aggregates.match(Filters.eq(Movie::title.name, "The Shawshank Redemption"))
Proyecto
Utilice el método project() para crear una etapa de pipeline $project que proyecte los campos de documento especificados. La proyección de campos en agregación sigue las mismas reglas que la proyección de campos en las consultas.
Tip
Aunque la proyección puede ser una instancia de cualquier clase que implemente Bson, es conveniente combinarla con el uso de Projections.
El siguiente ejemplo crea una etapa del pipeline que incluye los campos title y plot, pero excluye el campo _id:
Aggregates.project( Projections.fields( Projections.include(Movie::title.name, Movie::plot.name), Projections.excludeId()) )
Proyección de campos calculados
La etapa $project puede proyectar campos calculados también.
El siguiente ejemplo crea una etapa de canalización que proyecta el campo rated en un nuevo campo llamado rating, cambiando efectivamente el nombre del campo:
Aggregates.project( Projections.fields( Projections.computed("rating", "\$${Movie::rated.name}"), Projections.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 canalización de agregación, debe ser la primera etapa de la canalización.
El siguiente ejemplo crea una etapa de pipeline que genera documentos de muestra en la colección movies con un campo title:
Aggregates.documents( listOf( Document(Movie::title.name, "Steel Magnolias"), Document(Movie::title.name, "Back to the Future"), Document(Movie::title.name, "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.
val docsStage = database.aggregate<Document>( // ... )
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 canalización que selecciona aleatoriamente 5 documentos de la colección movies:
Aggregates.sample(5)
Sort
Utilice el método sort() para crear una etapa de pipeline $sort para ordenar según los criterios especificados.
Tip
Aunque el criterio de ordenación puede ser una instancia de cualquier clase que implemente Bson, es conveniente combinarlo con el uso de Sorts.
El siguiente ejemplo crea una etapa de pipeline que ordena en orden descendente según el valor del campo year y luego en orden ascendente según el valor del campo title:
Aggregates.sort( Sorts.orderBy( Sorts.descending(Movie::year.name), Sorts.ascending(Movie::title.name) ) )
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 en la colección movies:
Aggregates.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 fase de pipeline que limita la cantidad de documentos que se devuelven de la colección movies a 4:
Aggregates.limit(4)
Buscar
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 en la base de datos de muestra mflix:
Une el campo
_iddemoviescon el campomovie_idencommentsMuestra los resultados en el campo
joined_comments
Aggregates.lookup( "comments", "_id", "movie_id", "joined_comments" )
Full Join y subconsultas no correlacionadas
El siguiente ejemplo utiliza las colecciones ficticias orders y warehouses. Los datos se modelan utilizando las siguientes clases de datos de Kotlin:
data class Order( val id: Int, val customerId: Int, val item: String, val ordered: Int ) data class Inventory( val id: Int, val stockItem: String, val inStock: Int )
El ejemplo crea una etapa de pipeline que une las dos colecciones por el elemento y verifica si la cantidad disponible en el campo inStock es suficiente para cumplir con la cantidad ordered:
val variables = listOf( Variable("order_item", "\$item"), Variable("order_qty", "\$ordered") ) val pipeline = listOf( Aggregates.match( Filters.expr( Document("\$and", listOf( Document("\$eq", listOf("$\$order_item", "\$${Inventory::stockItem.name}")), Document("\$gte", listOf("\$${Inventory::inStock.name}", "$\$order_qty")) )) ) ), Aggregates.project( Projections.fields( Projections.exclude(Order::customerId.name, Inventory::stockItem.name), Projections.excludeId() ) ) ) val innerJoinLookup = Aggregates.lookup("warehouses", variables, pipeline, "stockData")
group
Utilice el group() método para crear una etapa de canalización $group para agrupar documentos mediante una expresión específica y generar un documento para 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 canalización que agrupa los documentos de la colección orders según el valor del campo customerId. Cada grupo acumula la suma y el promedio de los valores del campo ordered en los campos totalQuantity y averageQuantity:
Aggregates.group("\$${Order::customerId.name}", Accumulators.sum("totalQuantity", "\$${Order::ordered.name}"), Accumulators.avg("averageQuantity", "\$${Order::ordered.name}") )
Obtenga más información sobre los operadores de acumuladores en la sección del manual del servidor sobre Acumuladores.
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 se pueden realizar operaciones de agregación con estos acumuladores pick-n en MongoDB v5.2 o posterior.
Descubre con qué etapas del pipeline de agregación puedes utilizar los operadores de acumulación en la sección del manual del servidor sobre Acumuladores.
Los ejemplos del acumulador pick-n utilizan documentos de la colección movies en la base de datos sample-mflix.
Minnesota
El minN() constructor crea el acumulador $minN que devuelve datos de los documentos que contienen los n valores más bajos de una agrupación.
Tip
Los $minN $bottomN acumuladores y pueden realizar tareas similares. Consulte la Comparación de los acumuladores $minN y $bottomN para conocer el uso recomendado de cada uno.
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:
Aggregates.group( "\$${Movie::year.name}", Accumulators.minN( "lowestThreeRatings", "\$${Movie::imdb.name}.${Movie.IMDB::rating.name}", 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:
Aggregates.group( "\$${Movie::year.name}", Accumulators.maxN( "highestTwoRatings", "\$${Movie::imdb.name}.${Movie.IMDB::rating.name}", 2 ) )
Consulte la documentación de la API maxN() para obtener más información.
FirstN
El acumulador firstN() devuelve 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 dos primeros valores title de película, según el orden en que llegaron al escenario, agrupados por year:
Aggregates.group( "\$${Movie::year.name}", Accumulators.firstN( "firstTwoMovies", "\$${Movie::title.name}", 2 ) )
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 utilizar el método lastN() para mostrar los últimos tres valores title de películas, en función del orden en que llegaron a la etapa, agrupados por year:
Aggregates.group( "\$${Movie::year.name}", Accumulators.lastN( "lastThreeMovies", "\$${Movie::title.name}", 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 calificadas según imdb.rating, agrupadas por year.
Aggregates.group( "\$${Movie::year.name}", Accumulators.top( "topRatedMovie", Sorts.descending("${Movie::imdb.name}.${Movie.IMDB::rating.name}"), listOf("\$${Movie::title.name}", "\$${Movie::imdb.name}.${Movie.IMDB::rating.name}") ) )
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 según los valores runtime, agrupados por year.
Aggregates.group( "\$${Movie::year.name}", Accumulators.topN( "longestThreeMovies", Sorts.descending(Movie::runtime.name), listOf("\$${Movie::title.name}", "\$${Movie::runtime.name}"), 3 ) )
Consulte la documentación de la API topN() para obtener más información.
Fondo
El acumulador bottom() devuelve datos del último documento de 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.
Aggregates.group( "\$${Movie::year.name}", Accumulators.bottom( "shortestMovies", Sorts.descending(Movie::runtime.name), listOf("\$${Movie::title.name}", "\$${Movie::runtime.name}") ) )
Consulte la documentación de la API bottom() para obtener más información.
FondoN
El acumulador bottomN() devuelve datos de los documentos que contienen los valores n más bajos para el campo especificado.
Tip
Los $minN $bottomN acumuladores y pueden realizar tareas similares. Consulte la Comparación de los acumuladores $minN y $bottomN para conocer el uso recomendado de cada uno.
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:
Aggregates.group( "\$${Movie::year.name}", Accumulators.bottom( "lowestRatedTwoMovies", Sorts.descending("${Movie::imdb.name}.${Movie.IMDB::rating.name}"), listOf("\$${Movie::title.name}", "\$${Movie::imdb.name}.${Movie.IMDB::rating.name}"), ) )
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 lowestRatedTwoMovies:
Aggregates.unwind("\$${"lowestRatedTwoMovies"}")
Para conservar los documentos que tienen valores faltantes o null en el campo de arreglo, o donde el arreglo está vacío:
Aggregates.unwind( "\$${"lowestRatedTwoMovies"}", UnwindOptions().preserveNullAndEmptyArrays(true) )
Para incluir el índice de la matriz (en este ejemplo, en un campo llamado "position"):
Aggregates.unwind( "\$${"lowestRatedTwoMovies"}", 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 classic_movies:
Aggregates.out("classic_movies")
Unir
Utilice el merge() método para crear una etapa de canalización $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 nineties_movies utilizando las opciones por defecto:
Aggregates.merge("nineties_movies")
El siguiente ejemplo fusiona la canalización en la colección movie_ratings en la base de datos aggregation utilizando algunas opciones no predeterminadas que especifican reemplazar el documento si year y title coinciden; de lo contrario, insertar el documento:
Aggregates.merge( MongoNamespace("aggregation", "movie_ratings"), MergeOptions().uniqueIdentifier(listOf("year", "title")) .whenMatched(MergeOptions.WhenMatched.REPLACE) .whenNotMatched(MergeOptions.WhenNotMatched.INSERT) )
GraphLookup
Utilice el graphLookup() método para crear una etapa de canalización $graphLookup que realice una búsqueda recursiva en una colección específica para hacer coincidir un campo específico en un documento con un campo específico de otro documento.
El siguiente ejemplo utiliza la colección contacts. Los datos se modelan utilizando la siguiente clase de datos de Kotlin:
data class Users( val name: String, val friends: List<String>?, val hobbies: List<String>? )
El ejemplo calcula el grafo de reporte para usuarios en la colección contact, emparejando recursivamente el valor en el campo friends con el campo name:
Aggregates.graphLookup( "contacts", "\$${Users::friends.name}", Users::friends.name, Users::name.name, "socialNetwork" )
Con GraphLookupOptions, puede especificar la profundidad de recursión y el nombre del campo de profundidad, si lo desea. 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.
Aggregates.graphLookup( "contacts", "\$${Users::friends.name}", Users::friends.name, Users::name.name, "socialNetwork", GraphLookupOptions().maxDepth(2).depthField("degrees") )
Usando 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:
Aggregates.graphLookup( "contacts", "\$${Users::friends.name}", Users::friends.name, Users::name.name, "socialNetwork", GraphLookupOptions().maxDepth(1).restrictSearchWithMatch( Filters.eq(Users::hobbies.name, "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 de la colección movies por el campo genres y calcula el recuento de cada valor distinto:
Aggregates.sortByCount("\$${Movie::genres.name}"),
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 utiliza una colección books ficticia que contiene datos modelados utilizando la siguiente clase de datos Kotlin:
data class Libro(val titulo: String) data class Book(val title: String, val spanishTranslation: Libro)
Cada documento de entrada se reemplaza por el documento anidado en el campo spanishTranslation:
Aggregates.replaceRoot("\$${Book::spanishTranslation.name}")
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 añade dos nuevos campos, watched y type, a los documentos de entrada en la colección movie:
Aggregates.addFields( Field("watched", false), Field("type", "movie") )
Contar
Utilizar el método count() para crear una etapa de pipeline $count que contabiliza el número de documentos que ingresan a la etapa y asigna ese valor a un nombre de campo especificado. Si no especificas un campo, count() establece por defecto el nombre del campo como "count".
Tip
La etapa $count es una azúcar sintáctica para:
{ "$group":{ "_id": 0, "count": { "$sum" : 1 } } }
El siguiente ejemplo crea una etapa de canalización que genera el recuento de documentos entrantes en un campo llamado "total":
Aggregates.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.
Los siguientes ejemplos utilizan datos modelados con la siguiente clase de datos de Kotlin:
data class Screen( val id: String, val screenSize: Int, val manufacturer: String, val price: Double )
Este 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:
Aggregates.bucket("\$${Screen::screenSize.name}", listOf(0, 24, 32, 50, 70, 1000))
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.
Aggregates.bucket("\$${Screen::screenSize.name}", listOf(0, 24, 32, 50, 70), BucketOptions() .defaultBucket("monster") .output( Accumulators.sum("count", 1), Accumulators.push("matches", "\$${Screen::screenSize.name}") ) )
BucketAuto
Utilice el bucketAuto() método para crear una etapa de canalización $bucketAuto que determine automáticamente los límites de cada contenedor en su intento de distribuir los documentos de manera uniforme en una cantidad específica de contenedores.
Los siguientes ejemplos utilizan datos modelados con la siguiente clase de datos de Kotlin:
data class Screen( val id: String, val screenSize: Int, val manufacturer: String, val price: Double )
Este ejemplo crea una etapa de pipeline que intentará crear y distribuir de forma uniforme documentos en 5 compartimentos usando el valor de su campo price:
Aggregates.bucketAuto("\$${Screen::screenSize.name}", 5)
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 pipeline que intentará crear y distribuir uniformemente documentos en 5 grupos utilizando el valor de su campo price, configurando los límites de los grupos en potencias de 2 (2, 4, 8, 16, ...). También cuenta el número de documentos en cada bucket y calcula su promedio de 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.
Aggregates.bucketAuto( "\$${Screen::price.name}", 5, BucketAutoOptions() .granularity(BucketGranularity.POWERSOF2) .output(Accumulators.sum("count", 1), Accumulators.avg("avgPrice", "\$${Screen::price.name}")) )
Facet
Utilice el facet() método para crear una etapa de canalización $facet que permita la definición de canalizaciones paralelas.
Los siguientes ejemplos utilizan datos modelados con la siguiente clase de datos de Kotlin:
data class Screen( val id: String, val screenSize: Int, val manufacturer: String, val price: Double )
Este ejemplo crea una etapa de pipeline que ejecuta dos agregaciones en paralelo:
La primera agregación distribuye los documentos entrantes en 5 grupos según su campo
screenSize.La segunda agregación cuenta todos los fabricantes y devuelve su recuento, limitado a los cinco primeros.
Aggregates.facet( Facet( "Screen Sizes", Aggregates.bucketAuto( "\$${Screen::screenSize.name}", 5, BucketAutoOptions().output(Accumulators.sum("count", 1)) ) ), Facet( "Manufacturer", Aggregates.sortByCount("\$${Screen::manufacturer.name}"), Aggregates.limit(5) ) )
Establecer campos de ventana
Utilice el setWindowFields() método para crear una etapa de canalización $setWindowFields que permita usar 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 utiliza una colección ficticia de weather usando datos modelados con la siguiente clase de datos de Kotlin:
data class Weather( val localityId: String, val measurementDateTime: LocalDateTime, val rainfall: Double, val temperature: Double )
El ejemplo crea una etapa en la pipeline que calcula la lluvia acumulada y la temperatura promedio durante el último mes para cada localidad a partir de mediciones más detalladas presentadas en los campos rainfall y temperature:
val pastMonth = Windows.timeRange(-1, MongoTimeUnit.MONTH, Windows.Bound.CURRENT) val resultsFlow = weatherCollection.aggregate<Document>( listOf( Aggregates.setWindowFields("\$${Weather::localityId.name}", Sorts.ascending(Weather::measurementDateTime.name), WindowOutputFields.sum( "monthlyRainfall", "\$${Weather::rainfall.name}", pastMonth ), WindowOutputFields.avg( "monthlyAvgTemp", "\$${Weather::temperature.name}", pastMonth ) ) )
Densificar
Utiliza el método densify() para crear una etapa de pipeline $densify que genere una secuencia de documentos para cubrir un intervalo especificado.
Tip
Puede utilizar la etapa de agregación $densify() solo cuando se ejecute MongoDB v5.1 o una versión 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, ... }}
Estos documentos se modelan usando la siguiente clase de datos de Kotlin:
data class Weather( val id: ObjectId = ObjectId(), val position: Point, val ts: LocalDateTime )
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 la etapa de agregación densify() que realiza estas acciones debe parecerse a lo siguiente:
Aggregates.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
Puedes utilizar la etapa de agregación $fill() únicamente al ejecutar MongoDB 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}}
Estos documentos se modelan usando la siguiente clase de datos de Kotlin:
data class Weather( val id: ObjectId = ObjectId(), val hour: Int, val temperature: String?, val air_pressure: Double? )
Supongamos que necesita completar los puntos de datos de temperatura y presión del 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 generador de la etapa de agregación fill() que realiza estas acciones se parece a la siguiente:
val resultsFlow = weatherCollection.aggregate<Weather>( listOf( Aggregates.fill( FillOptions.fillOptions().sortBy(Sorts.ascending(Weather::hour.name)), FillOutputField.value(Weather::temperature.name, "23.6C"), FillOutputField.linear(Weather::air_pressure.name) ) ) ) resultsFlow.collect { println(it) }
Weather(id=6308a..., hour=1, temperature=23C, air_pressure=29.74) Weather(id=6308b..., hour=2, temperature=23.5C, air_pressure=29.75) Weather(id=6308b..., hour=3, temperature=23.6C, air_pressure=29.76)
Consulte la documentación de la API del paquete de relleno para obtener más información.
Búsqueda de texto completo en Atlas
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.
Tip
Disponible solo en Atlas para MongoDB v4.2 y posteriores
Este operador de pipeline de agregación sólo está disponible para colecciones alojadas en clústeres MongoDB Atlas que ejecuten la versión v4.2 o posterior y que están cubiertas por un Índice de MongoDB Search. Obtén más información sobre la configuración requerida y la funcionalidad de este operador en la documentación de MongoDB Search.
El siguiente ejemplo crea una etapa de pipeline que busca la palabra "futuro" en el campo title en la colección movies:
Aggregates.search( SearchOperator.text( SearchPath.fieldPath(Movie::title.name), "Future" ), SearchOptions.searchOptions().index("title") )
Obtenga más información sobre los constructores en la documentación de la API del paquete de búsqueda.
Métodos de operadores de búsqueda
El controlador Kotlin proporciona métodos auxiliares para los siguientes operadores:
Operador | Descripción |
|---|---|
Realiza una búsqueda de una palabra o frase que contenga una secuencia de caracteres de una cadena de entrada incompleta. | |
Combina dos o más operadores en una única query. | |
Verifica si un campo coincide con un valor que especificaste. Se asigna a los métodos | |
Comprueba si existe una ruta a un nombre de campo indexado específico en un documento. | |
Realiza una búsqueda de un arreglo de valores de número, fecha, booleano, objectId, uuid o string BSON en la ruta determinada y retorna documentos donde el valor del campo coincide con cualquier valor en el arreglo especificado. | |
Devuelve documentos similares a los documentos de entrada. | |
Permite consultar y puntuar valores numéricos, fechas y valores de puntos GeoJSON. | |
Realiza una búsqueda de documentos que contienen una secuencia ordenada de términos utilizando el analizador especificado en la configuración del índice. | |
Brinda soporte a las queries de una combinación de campos indexados y valores. | |
Permite la consulta y la calificación de valores numéricos, de fecha y de string. Se asigna a los métodos | |
Interpreta el campo de query como una expresión regular. | |
Realiza una búsqueda de texto completo utilizando el analizador que se especifique en la configuración del índice. | |
Permite consultas que utilizan caracteres especiales en la cadena de búsqueda que pueden coincidir con cualquier carácter. |
Ejemplo de etapa de búsqueda en el pipeline
Antes de que puedas ejecutar este ejemplo, debes crear un índice de búsqueda de MongoDB en la colección movies que tenga la siguiente definición:
{ "mappings": { "dynamic": true, "fields": { "title": { "analyzer": "lucene.keyword", "type": "string" }, "genres": { "normalizer": "lowercase", "type": "token" } } } }
Para obtener más información sobre la creación de índices de MongoDB Search, consulte la sección Índices de MongoDB Search y MongoDB Vector Search de la guía de Índices.
El siguiente código crea un escenario $search que tiene las siguientes especificaciones:
Comprueba que el arreglo
genresincluya"Comedy"Busca en el campo
fullplotla frase"new york"Coincide con
yearvalores entre1950y2000, ambos inclusiveBusca
titlevalores que comiencen con el término"Love"
data class Results(val title: String, val year: Int, val genres: List<String>) val searchStage = Aggregates.search( SearchOperator.compound() .filter( listOf( SearchOperator.`in`(SearchPath.fieldPath(Movie::genres.name), listOf("Comedy")), SearchOperator.phrase(SearchPath.fieldPath(Movie::fullplot.name), "new york"), SearchOperator.numberRange(SearchPath.fieldPath(Movie::year.name)).gtLt(1950, 2000), SearchOperator.wildcard(SearchPath.fieldPath(Movie::title.name), "Love *") ) ) ) val projectStage = Aggregates.project( Projections.include(Movie::title.name, Movie::year.name, Movie::genres.name)) val pipeline = listOf(searchStage, projectStage) val resultsFlow = ftsCollection.aggregate<Results>(pipeline) resultsFlow.collect { println(it) }
Results(title=Love at First Bite, year=1979, genres=[Comedy, Romance]) Results(title=Love Affair, year=1994, genres=[Comedy, Drama])
Para obtener más información sobre los métodos auxiliares de búsqueda de MongoDB, consulte la referencia de la interfaz SearchOperator en la documentación de la API de Driver Core.
MongoDB Search metadatos
Utiliza el método searchMeta() para crear una etapa de pipeline $searchMeta que devuelve únicamente la parte de metadatos de los resultados de las consultas de búsqueda de texto completo de Atlas.
Tip
Solo disponible en MongoDB Atlas v4.4.11 y versiones posteriores
Este operador del pipeline de agregación solo está disponible para MongoDB Atlas clústeres que ejecutan v4.4.11 y versiones posteriores. Para obtener una lista detallada de la disponibilidad de versiones, consulta la documentación de MongoDB Atlas en $searchMeta.
El siguiente ejemplo muestra los metadatos count para una etapa de agregación MongoDB Search:
Aggregates.searchMeta( SearchOperator.near(1985, 2, SearchPath.fieldPath(Movie::year.name)), SearchOptions.searchOptions().index("year") )
Obtén más información sobre este asistente consultando la documentación de la API searchMeta().