Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt — versiones en markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
Docs Menu

Modificar resultados de queries

En esta guía, aprenderá cómo ordenar, omitir, limitar y agrupar los resultados de una consulta utilizando la extensión MongoDB para Hibernate ORM.

Puede ordenar los resultados de la query por el valor de un campo especificado utilizando la cláusula order by en su instrucción de query. Por defecto, la cláusula order by ordena los documentos en orden ascendente. Para ordenar los documentos en orden descendente, adjunta la palabra clave desc al nombre del campo.

El siguiente ejemplo recupera documentos coincidentes de la colección sample_mflix.movies y los ordena por el campo year en orden descendente:

var sortResult = session.createQuery("from Movie where title = :t order by year desc", Movie.class)
.setParameter("t", "Cinderella")
.getResultList();
for (var m : sortResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
var sortResult = entityManager.createQuery("select m from Movie m where m.title = :t order by m.year desc", Movie.class)
.setParameter("t", "Cinderella")
.getResultList();
for (var m : sortResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}

Puedes omitir un número específico de documentos en los resultados de tu query, encadenando el método setFirstResult() a la query. Pasa la cantidad de documentos iniciales para omitir como argumento a este método.

El siguiente ejemplo ejecuta la misma query que el ejemplo anterior pero omite el primer documento coincidente en los resultados:

var skipResult = session.createQuery("from Movie where title = :t order by year desc", Movie.class)
.setParameter("t", "Cinderella")
.setFirstResult(1)
.getResultList();
for (var m : skipResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
var skipResult = entityManager.createQuery("select m from Movie m where m.title = :t order by m.year desc", Movie.class)
.setParameter("t", "Cinderella")
.setFirstResult(1)
.getResultList();
for (var m : skipResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}

Puedes limitar el número de documentos que tu query devuelve encadenando el método setMaxResults() a la query. Pase el número máximo de documentos a devolver como argumento a este método.

El siguiente ejemplo ejecuta la misma query que el ejemplo de ordenamiento, pero devuelve hasta dos documentos coincidentes en los resultados:

var limitResult = session.createQuery("from Movie where title = :t order by year desc", Movie.class)
.setParameter("t", "Cinderella")
.setMaxResults(2)
.getResultList();
for (var m : limitResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
var limitResult = entityManager.createQuery("select m from Movie m where m.title = :t order by m.year desc", Movie.class)
.setParameter("t", "Cinderella")
.setMaxResults(2)
.getResultList();
for (var m : limitResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}

Alternativamente, puede utilizar una cláusula limit en su instrucción HQL o JPQL para restringir el número de documentos que devuelve su query, como se muestra en el siguiente código:

var limitClauseResult = session.createQuery("from Movie where title = :t order by year desc limit 2", Movie.class)
.setParameter("t", "Cinderella")
.getResultList();
var limitClauseResult = entityManager.createQuery("select m from Movie m where m.title = :t order by m.year desc limit 2", Movie.class)
.setParameter("t", "Cinderella")
.getResultList();

Puedes agrupar documentos que comparten un valor en una sola fila de resultados utilizando la cláusula group by en tu consulta. La extensión Hibernate ORM traduce la cláusula group by a una etapa $group de MongoDB, donde cada clave de agrupación se convierte en un subcampo del campo _id.

Importante

Requisito clave de agrupación

Cada campo al que haga referencia en la cláusula select, having o order by de una consulta agrupada debe ser una clave de agrupación o parte de ella. Si hace referencia a un campo que la etapa $group no produce, la extensión Hibernate ORM genera una excepción FeatureNotSupportedException.

Una consulta agrupada tampoco puede usar la palabra clave distinct.

Para agrupar los resultados por el valor de uno o más campos, enumere los campos en la cláusula group by. Para agrupar por varios campos, separe los nombres de los campos con comas.

Este ejemplo realiza las siguientes operaciones:

  • Recupera documentos que tienen un valor title igual a "Hairspray" de la colección sample_mflix.movies.

  • Agrupa las películas por el campo year, que devuelve una fila por cada año de lanzamiento distinto.

  • Ordena los resultados por sus valores year en orden ascendente.

var groupResult = session.createQuery(
"select year from Movie where title = :title group by year order by year",
Integer.class)
.setParameter("title", "Hairspray")
.getResultList();
for (var year : groupResult) {
System.out.println("Year: " + year);
}
var groupResult = entityManager.createQuery(
"select m.year from Movie m where m.title = :title group by m.year order by m.year",
Integer.class)
.setParameter("title", "Hairspray")
.getResultList();
for (var year : groupResult) {
System.out.println("Year: " + year);
}

La extensión Hibernate ORM traduce esta consulta al siguiente flujo de trabajo. La cláusula where se convierte en una etapa $match que se ejecuta antes de la agrupación. La cláusula order by se convierte en una etapa $sort que ordena según la clave de agrupación:

[
{ "$match": { "title": { "$eq": "Hairspray" } } },
{ "$group": { "_id": { "year": "$year" } } },
{ "$sort": { "_id.year": 1 } },
{ "$project": { "_id#year": "$_id.year", "_id": 0 } }
]

Una clave de agrupación puede ser una expresión calculada en lugar de una referencia de campo. La extensión Hibernate ORM almacena la expresión en un subcampo generado _id llamado k<n>. Cuando se escribe la misma expresión en la cláusula select o having, la extensión Hibernate ORM la resuelve a ese subcampo en lugar de recalcularla.

La extensión ORM de Hibernate asocia una expresión a una clave de agrupación solo cuando ambas se escriben de forma idéntica. Por ejemplo, una clave de year + 1 no coincide con una ocurrencia de 1 + year.

También puede ordenar por una clave de expresión calculada. Escriba la expresión en la cláusula order by exactamente como la escribió en la cláusula group by.

El siguiente ejemplo agrupa los documentos que tienen un title de "Hairspray" por la década en la que fueron publicados y ordena los resultados en orden ascendente:

var groupExpressionResult = session.createQuery(
"select year / 10 * 10 from Movie where title = :title group by year / 10 * 10 order by year / 10 * 10",
Integer.class)
.setParameter("title", "Hairspray")
.getResultList();
for (var decade : groupExpressionResult) {
System.out.println("Decade: " + decade);
}
var groupExpressionResult = entityManager.createQuery(
"select m.year / 10 * 10 from Movie m where m.title = :title group by m.year / 10 * 10 order by m.year / 10 * 10",
Integer.class)
.setParameter("title", "Hairspray")
.getResultList();
for (var decade : groupExpressionResult) {
System.out.println("Decade: " + decade);
}

La extensión Hibernate ORM traduce esta consulta al siguiente flujo de trabajo, en el que las etapas $sort y $project leen la clave de agrupación de _id.k0 en lugar de recalcular la expresión:

[
{ "$match": { "title": { "$eq": "Hairspray" } } },
{
"$group": {
"_id": {
"k0": {
"$multiply": [
{ "$toInt": { "$divide": [ "$year", 10 ] } },
10
]
}
}
}
},
{ "$sort": { "_id.k0": 1 } },
{ "$project": { "#c_1": "$_id.k0", "_id": 0 } }
]

También puede seleccionar una expresión calculada que contenga una clave de agrupación. En este caso, la extensión Hibernate ORM agrupa por la clave y calcula la expresión a partir de la clave en la etapa $project.

Para obtener más información sobre las expresiones calculadas, consulte la sección "Uso de expresiones calculadas" en la guía "Especificar una consulta".

Para eliminar grupos de los resultados, utilice la cláusula having. La extensión Hibernate ORM utiliza la cláusula having para filtrar por la clave de agrupación. Puede combinar varias condiciones utilizando los operadores and y or.

Este ejemplo realiza las siguientes operaciones:

  • Recupera las películas "Hairspray" de la colección sample_mflix.movies.

  • Agrupa las películas por el campo year, que devuelve una fila por cada año de lanzamiento distinto.

  • Filtra los grupos para incluir solo valores year mayores que 2000.

  • Ordena los resultados por año en orden ascendente.

var havingResult = session.createQuery(
"select year from Movie where title = :title group by year having year > 2000 order by year",
Integer.class)
.setParameter("title", "Hairspray")
.getResultList();
for (var year : havingResult) {
System.out.println("Year: " + year);
}
var havingResult = entityManager.createQuery(
"select m.year from Movie m where m.title = :title group by m.year having m.year > 2000 order by m.year",
Integer.class)
.setParameter("title", "Hairspray")
.getResultList();
for (var year : havingResult) {
System.out.println("Year: " + year);
}

La extensión Hibernate ORM traduce esta consulta al siguiente flujo de procesamiento. La cláusula where se convierte en una etapa $match que se ejecuta antes de la agrupación. La cláusula having se convierte en una segunda etapa $match que se ejecuta después de la agrupación y filtra según la clave de agrupación:

[
{ "$match": { "title": { "$eq": "Hairspray" } } },
{ "$group": { "_id": { "year": "$year" } } },
{ "$match": { "_id.year": { "$gt": 2000 } } },
{ "$sort": { "_id.year": 1 } },
{ "$project": { "_id#year": "$_id.year", "_id": 0 } }
]

Para obtener más información sobre cómo realizar otras operaciones en tus datos de MongoDB, consulta la guía Realizar Operaciones CRUD.

Para aprender más sobre el uso de HQL y JPQL para ejecutar queries, consulte Una guía sobre el languaje del query de Hibernate en la documentación de Hibernate ORM.