Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Aggregates desarrolladores

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 Java de MongoDB.

Para aprender más sobre la agregación, consulta nuestra Guía de agregación. Para aprender cómo crear operaciones de expresión con métodos Java detectables y seguros en cuanto a tipos para usar en tus agregaciones, consulta Operaciones de expresión de agregación.

Tip

Para mayor brevedad, puedes optar por importar métodos estáticos de las siguientes clases para que tus consultas sean más concisas:

  • Aggregates

  • Filters

  • Projections

  • Sorts

  • 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.Accumulators.*;
import static com.mongodb.client.model.search.SearchPath.fieldPath;
import static com.mongodb.client.model.search.VectorSearchOptions.exactVectorSearchOptions;
import static java.util.Arrays.asList;

Los ejemplos en esta página asumen estas importaciones estáticas, además de importar estáticamente el método asList().

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");
collection.aggregate(asList(matchStage, sortByCountStage)).forEach(doc -> System.out.println(doc));

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 conveniente combinarlo con el uso de la clase Filtros.

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"));

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 de pipeline que excluye el campo _id pero incluye los campos title y plot:

project(fields(include("title", "plot"), excludeId()));

La etapa $project puede proyectar campos calculados también.

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()));

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.

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);

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:

sort(orderBy(descending("year"), ascending("title")));

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);

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);

Utiliza el método lookup() para crear una etapa en la pipeline $lookup y realizar combinaciones y subconsultas no correlacionadas entre dos colecciones.

El siguiente ejemplo crea una etapa de pipeline que realiza una unión externa izquierda entre las colecciones movies y comments:

  • Une el campo _id de movies con el campo movie_id en comments

  • Muestra los resultados en el campo joined_comments:

lookup("comments", "_id", "movie_id", "joined_comments");

El siguiente ejemplo crea una etapa de pipeline que une dos colecciones, orders y warehouses, por el artículo y si la cantidad disponible es suficiente para cubrir la cantidad solicitada:

List<Variable<String>> variables = asList(new Variable<>("order_item", "$item"),
new Variable<>("order_qty", "$ordered"));
List<Bson> pipeline = asList(
match(expr(new Document("$and",
asList(new Document("$eq", asList("$$order_item", "$stock_item")),
new Document("$gte", asList("$instock", "$$order_qty")))))),
project(fields(exclude("stock_item"), excludeId())));
Bson innerJoinLookup = lookup("warehouses", variables, pipeline, "stockdata");

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"));

Obtenga más información sobre los operadores de acumulación en la sección del manual del servidor sobre <a class=\" \" target=\" \" href=\" \"> Acumuladores.

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.

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.

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.

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.

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:

group(
"$year",
lastN(
"last_three_movies",
new BsonString("$title"),
3
));

Consulta la documentación de lastN() API para más información.

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.

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.

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.

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.

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");

Para conservar los documentos que tienen valores faltantes o null en el campo de arreglo, o donde el arreglo está vacío:

unwind("$sizes", new UnwindOptions().preserveNullAndEmptyArrays(true));

Para incluir el índice de arreglo, en este ejemplo en un campo llamado "position":

unwind("$sizes", new UnwindOptions().includeArrayIndex("position"));

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");

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));

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")));

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"));

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");

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));

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 del pipeline que muestra la cantidad de documentos entrantes en un campo llamado "total":

count("total");

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")));

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 del pipeline que intentará crear y distribuir uniformemente documentos en 10 categorías 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 pipeline que intentará crear y distribuir uniformemente documentos en 10 cubos utilizando el valor de su campo price, estableciendo los límites de los cubos en potencias de 2 (2, 4, 8, 16, ...). También cuenta el número de documentos en cada grupo y calcula su price promedio 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")));

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)));

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", Sorts.ascending("measurementDateTime"),
WindowOutputFields.sum("monthlyRainfall", "$rainfall", pastMonth),
WindowOutputFields.avg("monthlyAvgTemp", "$temperature", pastMonth));

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, ... }}

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.

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}}

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_pressure para la hora "2" utilizando la interpolación lineal para calcular el valor.

  • Establece el valor faltante de temperature en "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.

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 en el campo title texto que contenga la palabra "Futuro":

Bson textSearch = Aggregates.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.

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.

Tip

Solo disponible en Atlas para MongoDB v4.4.11 y posteriores

Este operador de pipeline de agregación sólo está disponible en los clústeres de MongoDB Atlas que ejecutan la versión4.4.11 y posteriores. Para obtener una lista detallada de la disponibilidad de versiones, consulte la documentación de MongoDB Atlas sobre $searchMeta.

El siguiente ejemplo muestra los metadatos count para una etapa de agregación MongoDB Search:

Aggregates.searchMeta(
SearchOperator.near(2010, 1, fieldPath("year")));

Obtén más información sobre este asistente consultando la documentación de la API searchMeta().

Volver

Desarrolladores

En esta página