Docs Menu
Docs Home
/ /

Especifica un query

En esta guía, puede aprender a utilizar la extensión MongoDB para Hibernate ORM para especificar una consulta de base de datos.

Puede refinar el conjunto de documentos que devuelve una consulta creando un filtro de consulta. Un filtro de consulta es una expresión que especifica los criterios de búsqueda que MongoDB utiliza para encontrar documentos en una operación de lectura o escritura. Para crear filtros de consulta de MongoDB, utilice sentencias de lenguaje de consulta de Hibernate (HQL) o lenguaje de consulta de persistencia de Jakarta (JPQL).

Tip

Para obtener más información sobre la sintaxis HQL y JPQL, consulte Una guía para el lenguaje de consulta Hibernate en la documentación de Hibernate ORM.

Nota

Soporte de query

La extensión MongoDB para Hibernate ORM no es compatible con todas las funciones de consulta de MongoDB e Hibernate. Para obtener más información, consulte Consulta de soporte en la página de compatibilidad de funciones.

Los ejemplos de esta guía utilizan el Movie Entidad que representa la sample_mflix.movies colección de los conjuntos de datos de muestra del Atlas. La Movie entidad tiene la siguiente definición:

import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import java.util.List;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
private ObjectId id;
private String title;
private String plot;
private int year;
private List<String> cast;
public Movie(String title, String plot, int year, List<String> cast) {
this.title = title;
this.plot = plot;
this.year = year;
this.cast = cast;
}
public Movie() {
}
public ObjectId getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPlot() {
return plot;
}
public void setPlot(String plot) {
this.plot = plot;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public List<String> getCast() {
return cast;
}
public void setCast(List<String> cast) {
this.cast = cast;
}
}

Para aprender a crear una aplicación Java que use la extensión MongoDB para Hibernate ORM para interactuar con esta colección de muestra de MongoDB, consulte el tutorial Primeros pasos.

Importante

Contextos de Persistencia

Para que Hibernate ORM interactúe con la base de datos, debe ejecutar operaciones dentro de un contexto de persistencia mediante Hibernate Session o Jakarta Persistence EntityManager. Utilice HQL para definir consultas de sesión y JPQL para definir consultas del administrador de entidades.

Antes de ejecutar los ejemplos de esta guía, asegúrese de agregar un contexto de persistencia y un código de administración de transacciones a su aplicación que se parezca al siguiente código:

var sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
// ... Perform CRUD operations here
tx.commit();
session.close();
sf.close();

Para utilizar una sesión, debes crear un archivo HibernateUtil.java que configure un SessionFactory. Para obtener más información, consulta el paso Configura tu aplicación del tutorial Comenzar.

// Replace <persistence unit> with the name of your persistence unit in the persistence.xml file
EntityManagerFactory emf = Persistence.createEntityManagerFactory("<persistence unit>");
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
// ... Perform CRUD operations here
entityManager.getTransaction().commit();
entityManager.close();
emf.close;

Para usar un,EntityManager debe crear un persistence.xml archivo que declare una unidad de persistencia. Para obtener más información, consulte el Tutorial sobre el uso de las API estándar de JPA en la documentación de Hibernate ORM.

Para consultar sus datos de MongoDB, llame al método createQuery() en una sesión o un gestor de entidades. A continuación, especifique los criterios de coincidencia en una declaración de lenguaje de consulta de Hibernate (HQL) o de lenguaje de consulta de persistencia de Jakarta (JPQL).

En esta sección se describe cómo realizar las siguientes operaciones de consulta:

Para recuperar todos los documentos de una colección, pase una instrucción SELECT básica al método createQuery(). En esta instrucción, especifique la entidad que representa la colección que desea consultar.

El siguiente ejemplo recupera los valores title de todos los documentos de la colección sample_mflix.movies consultando la entidad Movie:

var allDocs = session.createQuery("select title from Movie", String.class)
.getResultList();
for (var t : allDocs) {
System.out.println("Title: " + t);
}
Title: A Corner in Wheat
Title: Gertie the Dinosaur
Title: The Perils of Pauline
Title: Civilization
Title: Where Are My Children?
...
var allDocs = entityManager.createQuery("select m.title from Movie m", String.class)
.getResultList();
for (var t : allDocs) {
System.out.println("Title: " + t);
}
Title: A Corner in Wheat
Title: Gertie the Dinosaur
Title: The Perils of Pauline
Title: Civilization
Title: Where Are My Children?
...

Para recuperar documentos que cumplan criterios específicos, pase una sentencia SELECT con una cláusula where al método createQuery(). En esta sentencia, especifique la entidad que representa la colección que desea consultar y los criterios de coincidencia.

El siguiente ejemplo recupera documentos que tienen un valor title de "Romeo and Juliet" de la colección sample_mflix.movies:

var matchingDocs = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Romeo and Juliet")
.getResultList();
for (var m : matchingDocs) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
Title: Romeo and Juliet, Year: 1936
Title: Romeo and Juliet, Year: 1968
var matchingDocs = entityManager.createQuery("select m from Movie m where m.title = :t", Movie.class)
.setParameter("t", "Romeo and Juliet")
.getResultList();
for (var m : matchingDocs) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
Title: Romeo and Juliet, Year: 1936
Title: Romeo and Juliet, Year: 1968

Para recuperar un solo documento que coincida con criterios específicos, encadene el método getSingleResult() al método createQuery().

El siguiente ejemplo recupera un único documento que tiene un valor title de "Best in Show" de la colección sample_mflix.movies:

var singleResult = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Best in Show")
.getSingleResult();
System.out.println("Title: " + singleResult.getTitle() + ", Year: " + singleResult.getYear());
Title: Best in Show, Year: 2000
var singleResult = entityManager.createQuery("select m from Movie m where m.title = :t", Movie.class)
.setParameter("t", "Best in Show")
.getSingleResult();
System.out.println("Title: " + singleResult.getTitle() + ", Year: " + singleResult.getYear());
Title: Best in Show, Year: 2000

Importante

Errores NonUniqueResultException

Si su consulta coincide con varios documentos, el getSingleResult() método genera un NonUniqueResultException error. Para evitar este error, asegúrese de que su consulta coincida solo con un documento o limite los resultados a uno solo.

En lugar de utilizar declaraciones HQL o JPQL para crear filtros de consulta, puede utilizar la API de criterios de persistencia de Jakarta para crear consultas de tipos seguros mediante programación.

Para crear una consulta utilizando la API de criterios, realice las siguientes acciones:

  1. Crea un objeto CriteriaBuilder desde una sesión o un administrador de entidades.

  2. Crear un objeto CriteriaQuery desde el generador y especificar la entidad a query.

  3. Utilice los métodos de consulta proporcionados por la clase CriteriaQuery para especificar sus criterios de consulta.

Tip

Para obtener más información sobre la API de criterios, consulte Uso de la API de criterios para crear consultas en la documentación de Jakarta EE.

El siguiente ejemplo utiliza la API de Criteria para recuperar todos los documentos que tienen un valor de year igual a 1925 de la colección sample_mflix.movies:

CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Movie> cq = cb.createQuery(Movie.class);
Root<Movie> movieRoot = cq.from(Movie.class);
cq.select(movieRoot).where(cb.equal(movieRoot.get("year"), 1925));
session.createQuery(cq).getResultList()
.forEach(m -> System.out.println(m.getTitle()));
Lady Windermere's Fan
Clash of the Wolves
Grass: A Nation's Battle for Life
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Movie> cq = cb.createQuery(Movie.class);
Root<Movie> movieRoot = cq.from(Movie.class);
cq.select(movieRoot).where(cb.equal(movieRoot.get("year"), 1925));
entityManager.createQuery(cq).getResultList()
.forEach(m -> System.out.println(m.getTitle()));
Lady Windermere's Fan
Clash of the Wolves
Grass: A Nation's Battle for Life

Para ejecutar consultas MongoDB que actualmente no son compatibles con la extensión ORM de Hibernate, puede pasar su consulta como una declaración de lenguaje de consulta MongoDB (MQL) al método createNativeQuery().

Para aprender a ejecutar consultas nativas, consulte la guía Realizar consultas nativas.

En esta sección se describe cómo utilizar operadores para crear los siguientes tipos de filtros de consulta:

Tip

Esta sección no describe todos los operadores de consulta disponibles. Para ver una lista completa, consulte "Expresiones de operador" en la guía de consultas ORM de Hibernate.

Nota

La extensión ORM de Hibernate no admite todos los operadores de comparación, incluidos LIKE BETWEENy. Para obtener más información sobre las limitaciones de compatibilidad, consulte Compatibilidad de consultas en la página de compatibilidad de funciones.

Puede utilizar los siguientes operadores en sus declaraciones de consulta para comparar valores de campo con valores de consulta especificados:

  • =: Igualdad de coincidencia

  • <>: Coincidencia de desigualdades

  • >: Mayor que las comparaciones

  • >=: Comparaciones de mayor o igual

  • <:Menos que comparaciones

  • <=: Comparaciones menores o iguales

El siguiente ejemplo recupera documentos que tienen un valor year mayor o igual a 2015 de la colección sample_mflix.movies:

var comparisonResult = session.createQuery("from Movie where year >= :y", Movie.class)
.setParameter("y", 2015)
.getResultList();
for (var m : comparisonResult) {
System.out.println("Title: " + m.getTitle());
}
Title: Jurassic World
Title: The Stanford Prison Experiment
Title: Ex Machina
Title: Ant-Man
Title: The Danish Girl
Title: The Wedding Ringer
Title: Good Ol' Boy
Title: A Tale of Love and Darkness
Title: Aloha
...
var comparisonResult = entityManager.createQuery("select m from Movie m where m.year >= :y", Movie.class)
.setParameter("y", 2015)
.getResultList();
for (var m : comparisonResult) {
System.out.println("Title: " + m.getTitle());
}
Title: Jurassic World
Title: The Stanford Prison Experiment
Title: Ex Machina
Title: Ant-Man
Title: The Danish Girl
Title: The Wedding Ringer
Title: Good Ol' Boy
Title: A Tale of Love and Darkness
Title: Aloha
...

Puede usar los siguientes operadores en sus sentencias de consulta para combinar múltiples criterios de consulta:

  • and:Cumple todos los criterios

  • or:Cumple cualquier criterio

  • not: Invert criteria

El siguiente ejemplo recupera un documento que tiene un valor title de "The Godfather" y un valor year de 1972 de la colección sample_mflix.movies:

var logicalResult = session.createQuery("from Movie where title = :t and year = :y", Movie.class)
.setParameter("t", "The Godfather")
.setParameter("y", 1972)
.getSingleResult();
System.out.println("Title: " + logicalResult.getTitle());
Title: The Godfather
var logicalResult = entityManager.createQuery("select m from Movie m where m.title = :t and m.year = :y", Movie.class)
.setParameter("t", "The Godfather")
.setParameter("y", 1972)
.getSingleResult();
System.out.println("Title: " + logicalResult.getTitle());
Title: The Godfather

En esta sección se describe cómo modificar los resultados de su consulta de las siguientes maneras:

Puede ordenar los resultados de una consulta por el valor de un campo específico usando la cláusula order by en su consulta. De forma predeterminada, la cláusula order by ordena los documentos en orden ascendente. Para ordenar los documentos en orden descendente, añada 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());
}
Title: Cinderella, Year: 2015
Title: Cinderella, Year: 1997
Title: Cinderella, Year: 1950
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());
}
Title: Cinderella, Year: 2015
Title: Cinderella, Year: 1997
Title: Cinderella, Year: 1950

Puede omitir un número específico de documentos en los resultados de su consulta encadenando el método setFirstResult() a la consulta. Pase el número de documentos iniciales que se omitirán 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());
}
Title: Cinderella, Year: 1997
Title: Cinderella, Year: 1950
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());
}
Title: Cinderella, Year: 1997
Title: Cinderella, Year: 1950

Puede limitar la cantidad de documentos que devuelve su consulta encadenando el método setMaxResults() a la consulta. Pase el número máximo de documentos a devolver como argumento a este método.

El siguiente ejemplo ejecuta la misma consulta que el ejemplo de ordenación, 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());
}
Title: Cinderella, Year: 2015
Title: Cinderella, Year: 1997
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());
}
Title: Cinderella, Year: 2015
Title: Cinderella, Year: 1997

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

Esta sección describe cómo ejecutar consultas en los siguientes campos:

Para recuperar un documento según su valor ObjectId, puede pasar este valor como argumento al método get(), si está usando una sesión, o al método find(), si está usando un administrador de entidades.

El siguiente ejemplo recupera un documento de la colección sample_mflix.movies por su valor ObjectId:

var movieById = session.get(Movie.class, new ObjectId("573a13a8f29313caabd1d53c"));
var movieById = entityManager.find(Movie.class, new ObjectId("573a13a8f29313caabd1d53c"));

Puede representar documentos incrustados de MongoDB creando @Struct incrustables agregados. No puede crear filtros de consulta para valores incrustables individuales, pero puede usar la extensión ORM de Hibernate para obtener @Struct incrustables agregados asociados a entidades principales específicas.

Tip

Para obtener más información sobre cómo representar documentos incrustados, consulte Datos incrustados en la guía Crear entidades.

Importante

Limitaciones de las consultas

Para obtener más información sobre las limitaciones de consulta para elementos integrables, consulte Compatibilidad de consultas de Hibernate en la página Compatibilidad de funciones.

El siguiente ejemplo recupera documentos con un valor title de "Hairspray" de la colección sample_mflix.movies. A continuación, el código recupera el campo awards, que almacena el incrustable agregado Awards @Struct, e imprime el campo wins del tipo incrustable Awards:

var embeddedResult = session.createQuery("select awards from Movie where title = :title", Awards.class)
.setParameter("title", "Hairspray")
.getResultList();
for (var a : embeddedResult) {
System.out.println("Award wins: " + a.getWins());
}
Award wins: 0
Award wins: 21
var embeddedResult = entityManager.createQuery("select m.awards from Movie m where m.title = :title", Awards.class)
.setParameter("title", "Hairspray")
.getResultList();
for (var a : embeddedResult) {
System.out.println("Award wins: " + a.getWins());
}
Award wins: 0
Award wins: 21

La extensión ORM de Hibernate admite las siguientes funciones para consultar campos de matriz:

  • array_contains(): Coincidir con documentos donde un campo de matriz contiene un valor especificado

  • array_contains_nullable(): Coincide con documentos donde un campo de matriz contiene un valor específico, incluidos los valores null

  • array_includes(): Coincidir con documentos donde un campo de matriz incluye otro valor de matriz

  • array_includes_nullable(): Coincidir con documentos donde un campo de matriz incluye otro valor de matriz, incluidos valores null

Tip

Para obtener más información sobre las funciones de matriz, consulte Funciones para trabajar con matrices en la guía del usuario de Hibernate ORM.

El siguiente ejemplo utiliza la función array_contains() para recuperar documentos que tienen el valor "Kathryn Hahn" en el campo de matriz cast de la colección sample_mflix.movies:

var arrayResult = session.createQuery("from Movie where array_contains(cast, :actor)", Movie.class)
.setParameter("actor", "Kathryn Hahn")
.getResultList();
for (var m : arrayResult) {
System.out.println("Title: " + m.getTitle());
}
Title: How to Lose a Guy in 10 Days
Title: The Secret Life of Walter Mitty
Title: Bad Words
Title: Afternoon Delight
Title: The D Train
var arrayResult = entityManager.createQuery("select m from Movie m where array_contains(m.cast, :actor)", Movie.class)
.setParameter("actor", "Kathryn Hahn")
.getResultList();
for (var m : arrayResult) {
System.out.println("Title: " + m.getTitle());
}
Title: How to Lose a Guy in 10 Days
Title: The Secret Life of Walter Mitty
Title: Bad Words
Title: Afternoon Delight
Title: The D Train

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

Para obtener más información sobre el uso de HQL y JPQL para ejecutar consultas, consulte Una guía para el lenguaje de consulta de Hibernate en la documentación de Hibernate ORM.

Volver

Operaciones CRUD