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

Especifica un query

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

Se puede refinar el conjunto de documentos que una query retorna creando un filtro de query. Un filtro de query es una expresión que especifica los criterios de búsqueda que MongoDB usa para emparejar documentos en una operación de lectura o guardado. Para crear filtros de query de MongoDB, utiliza Hibernate Query Language (HQL) o instrucciones Jakarta Persistence Query Language (JPQL).

Tip

Para obtener más información sobre la sintaxis de HQL y JPQL, consulta Una guía sobre Hibernate languaje del query en la documentación de Hibernate ORM.

Nota

Soporte de query

La extensión MongoDB para Hibernate ORM no admite todas las funcionalidades de query de MongoDB y Hibernate. Para obtener más información, consulta Soporte de query en la página de Compatibilidad de funciones.

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

import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import java.time.Instant;
import java.util.List;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
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;
private List<String> directors;
private Instant released;
@Embedded
private Awards awards;
@OneToMany(mappedBy = "movie", fetch = FetchType.LAZY)
private List<Comment> comments;
public Movie(String title, String plot, int year, List<String> cast, List<String> directors, Instant released, Awards awards) {
this.title = title;
this.plot = plot;
this.year = year;
this.cast = cast;
this.directors = directors;
this.released = released;
this.awards = awards;
}
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;
}
public List<String> getDirectors() {
return directors;
}
public void setDirectors(List<String> directors) {
this.directors = directors;
}
public Awards getAwards() {
return awards;
}
public void setAwards(Awards awards) {
this.awards = awards;
}
public Instant getReleased() {
return released;
}
public void setReleased(Instant released) {
this.released = released;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
}

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

Los ejemplos de código de esta página también utilizan el siguiente agregado incrustable Awards @Struct:

@Embeddable
@Struct(name = "Awards")
public class Awards {
private int wins;
private int nominations;
private String text;
public Awards(int wins, int nominations, String text) {
this.wins = wins;
this.nominations = nominations;
this.text = text;
}
public Awards() {
}
public int getWins() {
return wins;
}
public void setWins(int wins) {
this.wins = wins;
}
public int getNominations() {
return nominations;
}
public void setNominations(int nominations) {
this.nominations = nominations;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}

Importante

Contextos de Persistencia

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

Antes de ejecutar los ejemplos en esta guía, asegúrate de añadir código de contexto de persistencia y gestión de transacciones a tu aplicación que se asemeje 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, debes crear un archivo persistence.xml que declare una unidad de persistencia. Para aprender más, consulta el Tutorial utilizando APIs estándar JPA en la documentación de Hibernate ORM.

Antes de crear una instancia SessionFactory, debe establecer la propiedad de configuración com.mongodb.hibernate.semantics.nulls en MQL. Esta propiedad es obligatoria, no tiene un valor predeterminado y actualmente no acepta ningún otro valor. Si omite la propiedad o le asigna otro valor, la extensión Hibernate ORM generará una excepción HibernateException.

Cuando se establece com.mongodb.hibernate.semantics.nulls en MQL, la propiedad declara que el comportamiento relacionado con los valores nulos sigue el lenguaje de consulta de MongoDB (MQL) que produce la extensión ORM de Hibernate durante la traducción, y no la lógica de tres valores definida por la semántica de valores nulos de SQL.

Debido a que la extensión Hibernate ORM no garantiza una traducción específica, los resultados del comportamiento relacionado con valores nulos pueden cambiar entre versiones.

El siguiente ejemplo establece la propiedad com.mongodb.hibernate.semantics.nulls en su archivo hibernate.properties:

com.mongodb.hibernate.semantics.nulls=MQL

Puedes utilizar los siguientes operadores en tus instrucciones de query para comparar los valores de los campos con valores de query especificados:

  • =: Coincidencia de igualdad

  • <>Coincidencia de desigualdades

  • >: Comparaciones mayores que

  • >=: Comparaciones mayores o iguales

  • <: Comparaciones menores que

  • <=Comparaciones menor o igual que

El siguiente ejemplo recupera documentos que tienen un valor de 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());
}
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());
}

Un predicado de valor de fila compara una lista de campos entre paréntesis con una lista de valores entre paréntesis en una sola expresión. La extensión Hibernate ORM admite predicados de valor de fila que utilizan los siguientes operadores:

  • =: Coincidencia de igualdad

  • <>Coincidencia de desigualdades

  • IN y NOT IN: Comparación con una lista de filas de valores

Puede proporcionar los valores como parámetros vinculados o como literales, y cada lista debe contener el mismo número de componentes.

El siguiente ejemplo recupera documentos que tienen un valor title igual a "Jurassic World" y un valor year igual a 2015 de la colección sample_mflix.movies:

var rowValueResult = session.createQuery("from Movie where (title, year) = (:t, :y)", Movie.class)
.setParameter("t", "Jurassic World")
.setParameter("y", 2015)
.getResultList();
for (var m : rowValueResult) {
System.out.println("Title: " + m.getTitle());
}
var rowValueResult = entityManager.createQuery("select m from Movie m where (m.title, m.year) = (:t, :y)", Movie.class)
.setParameter("t", "Jurassic World")
.setParameter("y", 2015)
.getResultList();
for (var m : rowValueResult) {
System.out.println("Title: " + m.getTitle());
}

La extensión Hibernate ORM compara cada par de componentes por separado. El predicado de valor de fila anterior se traduce en la siguiente etapa $match:

{
"$match": {
"$and": [
{ "title": { "$eq": "Jurassic World" } },
{ "year": { "$eq": 2015 } }
]
}
}

Un predicado de valor de fila que utiliza el operador <> se traduce en la misma expresión $and envuelta en una expresión $nor.

Si comparas los campos con otra lista de campos, como en where (title1, year1) = (title2, year2), la extensión ORM de Hibernate traduce el predicado a una expresión $expr en su lugar.

Puedes usar un predicado de valor de fila en una cláusula SELECT. El predicado se evalúa como un valor booleano en la proyección.

Nota

Semántica nula

Los predicados de valor de fila siguen la semántica de valores nulos del lenguaje de consulta de MongoDB en lugar de la lógica ternaria del ORM de Hibernate, por lo que un predicado <> coincide con documentos en los que un componente es nulo o falta. Para obtener más información, consulte la sección «Comparar valores de campo con valores nulos» de esta guía.

Para comparar una fila de campos con varias filas de valores, utilice el operador IN. El siguiente ejemplo recupera documentos que coinciden con cualquiera de los dos pares title y year:

var rowValueInResult = session.createQuery(
"from Movie where (title, year) in (('Jurassic World', 2015), ('Ex Machina', 2015))", Movie.class)
.getResultList();
for (var m : rowValueInResult) {
System.out.println("Title: " + m.getTitle());
}
var rowValueInResult = entityManager.createQuery(
"select m from Movie m where (m.title, m.year) in (('Jurassic World', 2015), ('Ex Machina', 2015))", Movie.class)
.getResultList();
for (var m : rowValueInResult) {
System.out.println("Title: " + m.getTitle());
}

El predicado de valor de fila precedente se traduce en la siguiente etapa $match:

{
"$match": {
"$or": [
{ "$and": [
{ "title": { "$eq": "Jurassic World" } },
{ "year": { "$eq": 2015 } }
] },
{ "$and": [
{ "title": { "$eq": "Ex Machina" } },
{ "year": { "$eq": 2015 } }
] }
]
}
}

Si la lista contiene solo una fila de valores, el predicado se traduce a la expresión $and sola. Un predicado NOT IN se traduce a la expresión $or envuelta en una expresión $nor.

Importante

Comparación de pedidos

La extensión Hibernate ORM no admite predicados de valor de fila que utilicen los operadores >, >=, < o <=. Estos predicados provocan que la extensión Hibernate ORM genere una excepción FeatureNotSupportedException.

Cuando se compara un campo con null mediante un operador de comparación, la extensión Hibernate ORM aplica la semántica nula del lenguaje de consulta de MongoDB en lugar de la lógica ternaria que define Hibernate ORM.

Nota

Lógica ternaria de Hibernate para nulo

Hibernate ORM v6.3 y posteriormente evalúa una comparación con null como null, que un predicado trata como false. La extensión Hibernate ORM no implementa este comportamiento. Para obtener más información sobre las características que admite la extensión Hibernate ORM, consulte Compatibilidad con tipos de datos en la página Compatibilidad de características.

Los operadores de comparación de MongoDB evalúan tanto un campo faltante como un campo que almacena un valor null explícito con respecto a null. Como resultado, una comparación = null coincide con documentos en los que el campo almacena null y documentos en los que el campo está ausente. Una comparación <> null o != null coincide con documentos en los que el campo almacena cualquier otro valor.

El siguiente ejemplo utiliza el operador = para recuperar documentos que tienen un valor null o un valor cast faltante de la colección sample_mflix.movies:

var nullComparisonResult = session.createQuery("from Movie where cast = null", Movie.class)
.getResultList();
for (var m : nullComparisonResult) {
System.out.println("Title: " + m.getTitle());
}
var nullComparisonResult = entityManager.createQuery("select m from Movie m where m.cast = null", Movie.class)
.getResultList();
for (var m : nullComparisonResult) {
System.out.println("Title: " + m.getTitle());
}

La extensión Hibernate ORM traduce esta consulta a la siguiente etapa $match:

{
"$match": {
"cast": { "$eq": null }
}
}

Las comparaciones que utilizan los operadores >, >=, < y <= siguen el orden de comparación BSON de MongoDB para campos inexistentes. Dado que null es un tipo BSON propio, una comparación >= null o <= null coincide con documentos en los que el campo almacena null o está ausente. Una comparación > null o < null no coincide con ningún documento.

Para hacer coincidir null con valores faltantes usando un predicado en lugar de un operador de comparación, consulte las secciones IS NULL e IS NOT NULL de esta guía.

Puedes calcular un valor a partir de valores de campo, literales y parámetros de consulta. Luego, puedes devolver ese valor en una cláusula SELECT o compararlo en una cláusula WHERE. La extensión Hibernate ORM traduce una expresión calculada a una expresión de agregación de MongoDB.

La extensión Hibernate ORM admite los siguientes operadores aritméticos en expresiones calculadas:

  • +: Adición, que se traduce como $add

  • -: Resta, que se traduce en $subtract

  • *: Multiplicación, que se traduce en $multiply

  • /: División, que se traduce en $divide

  • Unario - y +

Nota

La división siempre devuelve un número entero.

El ORM de Hibernate traduce la división en una canalización de agregación de MongoDB al operador $divide de MongoDB, que siempre devuelve un double. La extensión del ORM de Hibernate trunca el resultado envolviendo $divide en $toInt, o en $toLong si el tipo de resultado es BIGINT. Este comportamiento se aplica al operador / y al método quot() de la API de Criteria, independientemente de si se habilita la configuración PORTABLE_INTEGER_DIVISION del ORM de Hibernate.

El operador div no es compatible.

También puede utilizar los operadores de comparación descritos en la sección "Uso de operadores de comparación" dentro de las expresiones calculadas.

Importante

Limitaciones del operando

Un operando de una expresión calculada debe ser una referencia a un campo, un literal o un parámetro de consulta. La extensión Hibernate ORM no admite llamadas a funciones como operandos.

Debido a que Hibernate ORM reescribe el operador % de HQL a una llamada a la función mod(), % tampoco es compatible. Para realizar una operación de módulo, utilice el método CriteriaBuilder.mod() de la API Criteria, que se traduce al operador $mod de MongoDB.

El método CriteriaBuilder.quot() de la API de Criteria se comporta de forma idéntica al operador /.

Al seleccionar una expresión calculada, la extensión Hibernate ORM agrega el valor calculado a la etapa $project. Si se le asigna un alias a la expresión mediante la palabra clave AS, la extensión Hibernate ORM utiliza dicho alias como clave de proyección. De lo contrario, genera una clave con el formato #c_<n>.

El siguiente ejemplo calcula la edad de cada película "Hairspray" en la colección sample_mflix.movies restando el valor del campo year de un parámetro de consulta:

var arithmeticResult = session.createQuery(
"select title, :currentYear - year as age from Movie where title = :title",
Object[].class)
.setParameter("currentYear", 2026)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : arithmeticResult) {
System.out.println("Title: " + row[0] + ", Age: " + row[1]);
}
var arithmeticResult = entityManager.createQuery(
"select m.title, :currentYear - m.year as age from Movie m where m.title = :title",
Object[].class)
.setParameter("currentYear", 2026)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : arithmeticResult) {
System.out.println("Title: " + row[0] + ", Age: " + row[1]);
}

La extensión Hibernate ORM traduce la expresión calculada anterior a la siguiente etapa $project:

{
"$project": {
"title": true,
"age": { "$subtract": [ 2026, "$year" ] },
"_id": 0
}
}

En la cláusula WHERE, puede comparar una expresión calculada con un valor o comparar dos valores de campo entre sí. Cuando ninguno de los lados de la comparación es una referencia directa a un campo o valor, la extensión Hibernate ORM envuelve la comparación en el operador $expr de MongoDB. Las comparaciones entre un campo y un valor siguen utilizando la forma compacta { field: { operator: value } }.

El siguiente ejemplo recupera "Hairspray" películas estrenadas menos de 20 años antes de 2026:

var computedFilterResult = session.createQuery(
"from Movie where title = :title and :currentYear - year < 20", Movie.class)
.setParameter("title", "Hairspray")
.setParameter("currentYear", 2026)
.getResultList();
for (var m : computedFilterResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
var computedFilterResult = entityManager.createQuery(
"select m from Movie m where m.title = :title and :currentYear - m.year < 20",
Movie.class)
.setParameter("title", "Hairspray")
.setParameter("currentYear", 2026)
.getResultList();
for (var m : computedFilterResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}

La extensión Hibernate ORM traduce la consulta anterior a la siguiente etapa $match, en la que la comparación title utiliza la forma compacta y la comparación calculada utiliza $expr:

{
"$match": {
"$and": [
{ "title": { "$eq": "Hairspray" } },
{ "$expr": { "$lt": [ { "$subtract": [ 2026, "$year" ] }, 20 ] } }
]
}
}

Puedes usar una comparación en una instrucción SELECT para devolver su resultado booleano en lugar de usar la comparación como un filtro.

El siguiente ejemplo devuelve el título de cada película "Hairspray" y si la película se estrenó después de 2000:

var comparisonResult = session.createQuery(
"select title, year > 2000 as isRecent from Movie where title = :title",
Object[].class)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : comparisonResult) {
System.out.println("Title: " + row[0] + ", Recent: " + row[1]);
}
var comparisonResult = entityManager.createQuery(
"select m.title, m.year > 2000 as isRecent from Movie m where m.title = :title",
Object[].class)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : comparisonResult) {
System.out.println("Title: " + row[0] + ", Recent: " + row[1]);
}

La extensión Hibernate ORM traduce la comparación anterior a la siguiente etapa $project:

{
"$project": {
"title": true,
"isRecent": { "$gt": [ "$year", 2000 ] },
"_id": 0
}
}

Una expresión CASE devuelve un valor diferente para cada condición que especifique. La extensión Hibernate ORM admite expresiones CASE simples y con búsqueda tanto de HQL como de JPQL:

  • Caso simple: La expresión que sigue a la palabra clave CASE se compara para comprobar si es igual al valor de cada cláusula WHEN. Un ejemplo de una expresión de caso simple es case year when 2000 then 'Modern' else 'Classic' end.

  • Caso de búsqueda: Cada cláusula WHEN especifica un predicado. Un ejemplo de una expresión de caso de búsqueda es case when year > 2000 then 'Modern' else 'Classic' end.

La extensión Hibernate ORM traduce una expresión CASE al operador $switch de MongoDB, que crea una rama para cada cláusula WHEN y evalúa las ramas en el orden en que se especifican. La cláusula ELSE se convierte en el valor default de $switch. Si se omite la cláusula ELSE, la expresión devuelve null cuando ninguna rama coincide.

Una expresión CASE puede devolver una expresión calculada, y puede utilizar una expresión CASE en las siguientes posiciones:

  • Una cláusula SELECT, como se muestra en el siguiente ejemplo.

  • Un operando de una comparación en una cláusula WHERE, que la extensión ORM de Hibernate envuelve en el operador $expr de MongoDB.

  • La cláusula SET de una instrucción de actualización masiva. Para ver un ejemplo, consulte la sección "Ejemplo de actualización múltiple basada en lógica condicional" en la guía "Realizar operaciones CRUD".

El siguiente ejemplo devuelve el título de cada película "Hairspray" y una etiqueta que depende del valor year de la película:

var caseResult = session.createQuery(
"select title, case when year > 2000 then 'Modern' else 'Classic' end as era "
+ "from Movie where title = :title",
Object[].class)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : caseResult) {
System.out.println("Title: " + row[0] + ", Era: " + row[1]);
}
var caseResult = entityManager.createQuery(
"select m.title, case when m.year > 2000 then 'Modern' else 'Classic' end as era "
+ "from Movie m where m.title = :title",
Object[].class)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : caseResult) {
System.out.println("Title: " + row[0] + ", Era: " + row[1]);
}

La extensión Hibernate ORM traduce la expresión CASE anterior a la siguiente etapa $project:

{
"$project": {
"title": true,
"era": {
"$switch": {
"branches": [
{ "case": { "$gt": [ "$year", 2000 ] }, "then": "Modern" }
],
"default": "Classic"
}
},
"_id": 0
}
}

Importante

Limitaciones de la expresión CASE

Debido a que una expresión CASE produce una expresión de agregación de MongoDB, no se puede usar en una posición que requiera una referencia de campo o un valor literal. La extensión Hibernate ORM genera una excepción FeatureNotSupportedException si se usa una expresión CASE:

  • en una cláusula ORDER BY, a menos que la misma expresión CASE sea una clave GROUP BY.

  • como la expresión de coincidencia de un predicado LIKE.

  • como expresión de prueba de un predicado IN o IS NULL.

  • como predicado de una cláusula WHERE en lugar de un operando de una.

La extensión Hibernate ORM admite los siguientes operadores de comparación de predicados en sus sentencias de consulta:

Nota

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

El predicado EXISTS coincide con los documentos que tienen un campo específico y devuelve solo un resultado para cada documento padre coincidente, independientemente de cuántos elementos de la matriz coincidan.

Nota

Limitaciones de subconsultas EXISTS

La extensión Hibernate ORM admite subconsultas EXISTS únicamente sobre un campo de matriz de la entidad principal, y únicamente en la cláusula WHERE. La extensión Hibernate ORM no admite subconsultas EXISTS que:

  • Consultar una entidad sin especificar primero un campo.

  • Comparar campos en el mismo documento principal.

  • Aparece en la cláusula SELECT

Para ver un ejemplo completo, consulte la sección "Consulta sobre elementos de una matriz incrustada" de esta guía.

El predicado BETWEEN coincide con los documentos que tienen un valor de campo dentro de un rango especificado.

El siguiente ejemplo utiliza el predicado BETWEEN para recuperar documentos que tienen un valor year entre 2012 y 2013, ambos inclusive, de la colección sample_mflix.movies:

var betweenResult = session.createQuery("from Movie where year between :start and :end", Movie.class)
.setParameter("start", 2012)
.setParameter("end", 2013)
.getResultList();
for (var m : betweenResult) {
System.out.println("Title: " + m.getTitle());
}
var betweenResult = entityManager.createQuery("select m from Movie m where m.year between :start and :end", Movie.class)
.setParameter("start", 2012)
.setParameter("end", 2013)
.getResultList();
for (var m : betweenResult) {
System.out.println("Title: " + m.getTitle());
}

La extensión Hibernate ORM traduce el predicado BETWEEN anterior a la siguiente etapa $match:

{
"$match": {
"year": { "$gte": 2012, "$lte": 2013 }
}
}

El predicado IN coincide con los documentos donde el valor de un campo es igual a cualquier valor de una lista específica. Puede proporcionar los valores de la lista como literales, parámetros con nombre o parámetros posicionales.

El siguiente ejemplo utiliza el predicado IN para recuperar documentos que tienen un valor year igual a 1994 o 1996 de la colección sample_mflix.movies:

var inResult = session.createQuery("from Movie where year in (:first, :second)", Movie.class)
.setParameter("first", 1994)
.setParameter("second", 1996)
.getResultList();
for (var m : inResult) {
System.out.println("Title: " + m.getTitle());
}
var inResult = entityManager.createQuery("select m from Movie m where m.year in (:first, :second)", Movie.class)
.setParameter("first", 1994)
.setParameter("second", 1996)
.getResultList();
for (var m : inResult) {
System.out.println("Title: " + m.getTitle());
}

La extensión Hibernate ORM traduce el predicado IN anterior a la siguiente etapa $match:

{
"$match": {
"year": { "$in": [ 1994, 1996 ] }
}
}

Una lista vacía es válida, pero nunca coincide con ningún documento. Por ejemplo, year in () no coincide con ningún documento.

Nota

Limitaciones del predicado IN

La extensión Hibernate ORM admite el predicado IN solo cuando el valor a la izquierda de IN es una ruta de campo. La extensión Hibernate ORM no admite los predicados IN que:

  • Toma una subconsulta como la lista de valores.

  • Comprueba un valor comparándolo con una expresión de matriz, como en :value in m.cast. Para comparar un valor con un campo de matriz, utiliza la función array_contains().

Para obtener más información sobre cómo consultar una matriz, consulte la sección "Consultar un campo de matriz" de esta guía.

El predicado NOT IN coincide con documentos en los que el valor de un campo no coincide con ningún valor de una lista específica. NOT IN acepta los mismos formatos de lista y tiene las mismas limitaciones que el predicado IN.

El siguiente ejemplo utiliza el predicado NOT IN para recuperar documentos que tienen un valor title distinto de "Romeo and Juliet" o "Best in Show" de la colección sample_mflix.movies. Dado que NOT IN excluye solo los valores enumerados, el ejemplo llama al método setMaxResults() para limitar el conjunto de resultados a diez documentos:

var notInResult = session.createQuery("from Movie where title not in (:first, :second)", Movie.class)
.setParameter("first", "Romeo and Juliet")
.setParameter("second", "Best in Show")
.setMaxResults(10)
.getResultList();
for (var m : notInResult) {
System.out.println("Title: " + m.getTitle());
}
var notInResult = entityManager.createQuery("select m from Movie m where m.title not in (:first, :second)", Movie.class)
.setParameter("first", "Romeo and Juliet")
.setParameter("second", "Best in Show")
.setMaxResults(10)
.getResultList();
for (var m : notInResult) {
System.out.println("Title: " + m.getTitle());
}

La extensión Hibernate ORM traduce el predicado NOT IN anterior a la siguiente etapa $match:

{
"$match": {
"title": { "$nin": [ "Romeo and Juliet", "Best in Show" ] }
}
}

Debido a que $nin compara cada documento con una lista vacía de valores, title not in () compara todos los documentos.

Nota

NO EN Limitaciones

La extensión Hibernate ORM admite el predicado NOT IN solo cuando el valor a la izquierda de NOT IN es una ruta de campo. La extensión Hibernate ORM no admite los predicados NOT IN que:

  • Toma una subconsulta como la lista de valores.

  • Comprueba un valor comparándolo con una expresión que contiene valores de matriz, como en :value not in m.cast.

Nota

Semántica nula

Los predicados de valor de fila siguen la semántica de valores nulos del lenguaje de consulta de MongoDB en lugar de la lógica ternaria del ORM de Hibernate, por lo que un predicado NOT IN coincide con documentos en los que un componente es nulo o falta. Para obtener más información, consulte la sección «Comparar valores de campo con valores nulos» de esta guía.

El predicado IS NULL coincide con los documentos que tienen un campo específico con un valor nulo o faltante.

Para comparar un campo con null utilizando un operador de comparación en lugar de un predicado, consulte la sección Comparar valores de campo con Null de esta guía.

El siguiente ejemplo utiliza el predicado IS NULL para recuperar documentos que tienen un valor faltante o null cast de la colección sample_mflix.movies:

var isNullResult = session.createQuery("from Movie where cast is null", Movie.class)
.getResultList();
for (var m : isNullResult) {
System.out.println("Title: " + m.getTitle());
}
var isNullResult = entityManager.createQuery("select m from Movie m where m.cast is null", Movie.class)
.getResultList();
for (var m : isNullResult) {
System.out.println("Title: " + m.getTitle());
}

La extensión Hibernate ORM traduce el predicado IS NULL precedente a la siguiente etapa $match, que coincide con los documentos donde el campo es explícitamente null o falta:

{
"$match": {
"cast": { "$eq": null }
}
}

El predicado IS NOT NULL coincide con los documentos que tienen un campo con un valor no nulo o no faltante.

El siguiente ejemplo utiliza el predicado IS NOT NULL para recuperar documentos que tienen un valor directors de la colección sample_mflix.movies:

var isNotNullResult = session.createQuery("from Movie where directors is not null", Movie.class)
.getResultList();
for (var m : isNotNullResult) {
System.out.println("Title: " + m.getTitle());
}
var isNotNullResultEm = entityManager.createQuery("select m from Movie m where m.directors is not null", Movie.class)
.getResultList();
for (var m : isNotNullResultEm) {
System.out.println("Title: " + m.getTitle());
}

La extensión Hibernate ORM traduce el predicado IS NOT NULL precedente a la siguiente etapa $match, que coincide con los documentos donde el campo existe y no es explícitamente null:

{
"$match": {
"directors": { "$ne": null }
}
}

El predicado LIKE distingue entre mayúsculas y minúsculas y coincide con documentos donde el valor de un campo coincide con un patrón especificado. El patrón se compara con el valor completo del campo y puede utilizar los siguientes caracteres comodín:

  • %: Coincide con cero o más caracteres.

  • _: Coincide exactamente con un carácter.

Para que coincida con un prefijo, incluya % al final del patrón, y para que coincida con un sufijo, incluya % al principio del patrón.

Tip

Personajes comodín de escape

Si desea que coincida con % o _ como carácter literal, utilice la cláusula ESCAPE. Por ejemplo, title like '100!%' escape '!' coincide con el valor "100%". Puede usar ESCAPE con %, _ o el propio carácter de escape. Si lo usa con cualquier otro carácter o lo deja al final del patrón, la extensión Hibernate ORM generará una excepción IllegalArgumentException.

El siguiente ejemplo utiliza el predicado LIKE para recuperar documentos que tienen un valor title que comienza con "W", seguido de cualquier carácter individual y luego "r", de la colección sample_mflix.movies:

var likeResult = session.createQuery("from Movie where title like 'W_r%'", Movie.class)
.getResultList();
for (var m : likeResult) {
System.out.println("Title: " + m.getTitle());
}
var likeResultEm = entityManager.createQuery("select m from Movie m where m.title like 'W_r%'", Movie.class)
.getResultList();
for (var m : likeResultEm) {
System.out.println("Title: " + m.getTitle());
}

La extensión Hibernate ORM traduce el predicado LIKE anterior a la siguiente etapa $match:

{
"$match": {
"title": { "$regex": /^W.r.*$/s }
}
}

Nota

Limitaciones del predicado LIKE

El valor que compare con LIKE debe ser una cadena literal, como '%War%'. La extensión Hibernate ORM no admite un parámetro vinculado (like :pattern), otro campo (like m.plot) o un valor calculado (like concat('War', '%')) para el patrón, y lanza un FeatureNotSupportedException si usa uno.

Para obtener más información sobre el predicado HQL LIKE, consulte la Guía del lenguaje de consulta de Hibernate en la documentación de Hibernate ORM.

El predicado NOT LIKE coincide con los documentos en los que el valor de un campo no coincide con el patrón especificado. La extensión Hibernate ORM niega el filtro $regex que produce el predicado LIKE y utiliza el mismo comportamiento de coincidencia de patrones y las mismas restricciones que el predicado LIKE.

El siguiente ejemplo utiliza el predicado NOT LIKE para recuperar documentos que tienen un valor title que no comienza con "The" de la colección sample_mflix.movies. Dado que el predicado coincide con la mayoría de los documentos, el ejemplo llama al método setMaxResults() para limitar el conjunto de resultados a cinco documentos:

var notLikeResult = session.createQuery("from Movie where title not like 'The%'", Movie.class)
.setMaxResults(5)
.getResultList();
for (var m : notLikeResult) {
System.out.println("Title: " + m.getTitle());
}
var notLikeResultEm = entityManager.createQuery("select m from Movie m where m.title not like 'The%'", Movie.class)
.setMaxResults(5)
.getResultList();
for (var m : notLikeResultEm) {
System.out.println("Title: " + m.getTitle());
}

La extensión Hibernate ORM traduce el predicado NOT LIKE anterior a la siguiente etapa $match:

{
"$match": {
"$nor": [
{ "title": { "$regex": /^The.*$/s } }
]
}
}

El predicado ILIKE es la forma insensible a mayúsculas y minúsculas del predicado LIKE. La extensión Hibernate ORM marca el filtro $regex que produce el predicado LIKE como insensible a mayúsculas y minúsculas y utiliza el mismo comportamiento de coincidencia de patrones y las mismas restricciones que el predicado LIKE.

El siguiente ejemplo utiliza el predicado ILIKE para recuperar documentos que tienen un valor title que contiene "Star" de la colección sample_mflix.movies:

var ilikeResult = session.createQuery("from Movie where title ilike '%Star%'", Movie.class)
.getResultList();
for (var m : ilikeResult) {
System.out.println("Title: " + m.getTitle());
}
var ilikeResultEm = entityManager.createQuery("select m from Movie m where m.title ilike '%Star%'", Movie.class)
.getResultList();
for (var m : ilikeResultEm) {
System.out.println("Title: " + m.getTitle());
}

La extensión Hibernate ORM traduce el predicado ILIKE anterior a la siguiente etapa $match:

{
"$match": {
"title": { "$regex": /^.*Star.*$/is }
}
}

El predicado NOT ILIKE es la forma insensible a mayúsculas y minúsculas del predicado NOT LIKE. La extensión ORM de Hibernate niega el filtro $regex insensible a mayúsculas y minúsculas que produce el predicado ILIKE y utiliza el mismo comportamiento de coincidencia de patrones y las mismas restricciones que el predicado LIKE.

El siguiente ejemplo utiliza el predicado NOT ILIKE para recuperar documentos que tienen un valor title que no contiene "The" de la colección sample_mflix.movies. Dado que el predicado coincide con la mayoría de los documentos, el ejemplo llama al método setMaxResults() para limitar el conjunto de resultados a cinco documentos:

var notIlikeResult = session.createQuery("from Movie where title not ilike '%The%'", Movie.class)
.setMaxResults(5)
.getResultList();
for (var m : notIlikeResult) {
System.out.println("Title: " + m.getTitle());
}
var notIlikeResultEm = entityManager.createQuery("select m from Movie m where m.title not ilike '%The%'", Movie.class)
.setMaxResults(5)
.getResultList();
for (var m : notIlikeResultEm) {
System.out.println("Title: " + m.getTitle());
}

La extensión Hibernate ORM traduce el predicado NOT ILIKE anterior a la siguiente etapa $match:

{
"$match": {
"$nor": [
{ "title": { "$regex": /^.*The.*$/is } }
]
}
}

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

  • and: Coincidencia con todos los criterios

  • orCoincide con cualquier criterio

  • not: No cumple con los criterios

El siguiente ejemplo recupera un documento que tiene un valor de title de "The Godfather" y un valor de 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());
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());

Para recuperar un documento en función de su valor ObjectId, puedes pasar ese valor como argumento al método get(), si estás usando una sesión, o al método find(), si usas un gestor 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"));

Puedes representar documentos incrustados de MongoDB creando elementos incrustables agregados @Struct. Luego, puedes usar la extensión Hibernate ORM para obtener elementos incrustables agregados @Struct asociados con entidades principales específicas.

Tip

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

El siguiente ejemplo recupera documentos que tienen un valor de title de "Hairspray" de la colección sample_mflix.movies. Luego, el código recupera el campo awards, que almacena Awards agregado @Struct integrable, e imprime el campo wins del tipo integrable 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());
}
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());
}

Puedes hacer referencia a un campo de un tipo incrustable usando una expresión de ruta con puntos en las cláusulas SELECT, WHERE, ORDER BY y UPDATE de una consulta HQL o JPQL. También puedes encadenar varios nombres de incrustables en una expresión de ruta para hacer referencia a un campo de un incrustable anidado dentro de otro incrustable.

Importante

Limitaciones de query

Las expresiones de ruta no admiten campos incrustables que utilicen la anotación @ColumnTransformer para definir una expresión de lectura personalizada.

La extensión Hibernate ORM también rechaza las siguientes asignaciones incrustables agregadas @Struct cuando construye el modelo de entidad:

  • Un elemento incrustable agregado @Struct utilizado como un campo @Id

  • Una jerarquía incrustable agregada polimórfica @Struct

No se puede utilizar una expresión de ruta para hacer referencia a un campo en estos tipos.

El siguiente ejemplo utiliza una expresión de ruta para filtrar documentos en la colección sample_mflix.movies. Hay dos películas "Hairspray" en la colección sample_mflix.movies. Una película "Hairspray" es de 1998 y la otra es de 2007. La consulta coincide con los documentos que tienen un valor title igual a "Hairspray" y un valor awards.wins mayor que 10:

var matchingDocument = session.createQuery("from Movie where title = :title and awards.wins > :minWins", Movie.class)
.setParameter("title", "Hairspray")
.setParameter("minWins", 10)
.getResultList();
for (var m : matchingDocument) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
var matchingDocument = entityManager.createQuery("select m from Movie m where m.title = :title and m.awards.wins > :minWins", Movie.class)
.setParameter("title", "Hairspray")
.setParameter("minWins", 10)
.getResultList();
for (var m : matchingDocument) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}

Cuando un campo de su entidad almacena una matriz de elementos incrustables agregados @Struct, puede usar una subconsulta EXISTS para encontrar documentos principales en los que al menos un elemento de esa matriz cumpla con sus criterios. La extensión Hibernate ORM traduce la subconsulta al operador $elemMatch de MongoDB, que aplica todos los criterios al mismo elemento de la matriz.

Nota

Utilice la base de datos sample_restaurants para esta sección.

Los ejemplos de esta sección utilizan la colección sample_restaurants.restaurants en lugar de la colección sample_mflix.movies que se utiliza en otras partes de esta guía.

Para ejecutar estos ejemplos, conéctese a la base de datos sample_restaurants en su cadena de conexión. Para obtener más información sobre la base de datos sample_restaurants, consulte los conjuntos de datos de ejemplo de Atlas.

La siguiente entidad Restaurant se asigna a la colección restaurants y almacena una lista de elementos incrustables Grade en su campo grades:

package org.example;
import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import jakarta.persistence.Column;
import org.bson.types.ObjectId;
import java.util.List;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "restaurants")
public class Restaurant {
@Id
@ObjectIdGenerator
@Column(name = "_id")
private ObjectId id;
private String name;
private String borough;
private List<Grade> grades;
public Restaurant(String name, String borough, List<Grade> grades) {
this.name = name;
this.borough = borough;
this.grades = grades;
}
public Restaurant() {
}
public ObjectId getId() {
return id;
}
public void setId(ObjectId id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBorough() {
return borough;
}
public void setBorough(String borough) {
this.borough = borough;
}
public List<Grade> getGrades() {
return grades;
}
public void setGrades(List<Grade> grades) {
this.grades = grades;
}
}

El siguiente elemento incrustable agregado Grade @Struct representa cada elemento del array grades:

package org.example;
import jakarta.persistence.*;
import org.hibernate.annotations.Struct;
@Embeddable
@Struct(name = "Grade")
public class Grade {
private String grade;
private int score;
public Grade() {
}
public Grade(String grade, int score) {
this.grade = grade;
this.score = score;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}

Tip

Para obtener más información sobre las matrices de elementos incrustables, consulte Datos incrustados en la guía Crear entidades.

Los documentos de la colección restaurants se parecen a los siguientes:

{
"_id": { "$oid": "5eb3d668b31de5d588f4292a" },
"name": "Morris Park Bake Shop",
"borough": "Bronx",
"cuisine": "Bakery",
"grades": [
{ "date": { "$date": 1393804800000 }, "grade": "A", "score": 2 },
{ "date": { "$date": 1299715200000 }, "grade": "B", "score": 14 }
]
}

El siguiente ejemplo recupera restaurantes que tienen al menos un elemento de la matriz grades con un valor grade igual a "B" y un valor score igual a 12. Dado que ambos criterios aparecen en la misma subconsulta, deben coincidir con el mismo elemento de la matriz:

var existsResult = session.createQuery(
"from Restaurant r where exists (select g.grade from r.grades g where g.grade = :grade and g.score = :score)",
Restaurant.class)
.setParameter("grade", "B")
.setParameter("score", 12)
.getResultList();
for (var r : existsResult) {
System.out.println("Name: " + r.getName());
}
var existsResultEm = entityManager.createQuery(
"select r from Restaurant r where exists (select g.grade from r.grades g where g.grade = :grade and g.score = :score)",
Restaurant.class)
.setParameter("grade", "B")
.setParameter("score", 12)
.getResultList();
for (var r : existsResultEm) {
System.out.println("Name: " + r.getName());
}

La extensión Hibernate ORM traduce la subconsulta EXISTS anterior a la siguiente etapa $match:

{
"$match": {
"grades": {
"$elemMatch": {
"grade": { "$eq": "B" },
"score": { "$eq": 12 }
}
}
}
}

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

  • array_contains(): Coincide documentos donde un campo de arreglo contiene un valor especificado

  • array_contains_nullable(): Coincidir con documentos donde un campo de arreglo contiene un valor especificado, incluyendo valores null

  • array_includes(): Coincide con documentos donde un campo de arreglo incluye otro valor de arreglo

  • array_includes_nullable()Coincidir con documentos donde un campo de arreglo incluya otro valor de arreglo, incluidos valores null

Tip

Para aprender más sobre las funciones de arrays, consulte Funciones para el manejo de arrays en la guía de 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 arreglo 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());
}
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());
}

En las consultas HQL y JPQL, puede utilizar funciones de agregación para agrupar y resumir los resultados de la consulta, o para filtrar los resultados agrupados mediante una cláusula HAVING. HQL y JPQL admiten las siguientes funciones de agregación:

  • count()

  • sum()

  • avg()

  • min()

  • max()

Nota

Requisitos de AGRUPAR POR

Las funciones de agregación requieren una cláusula GROUP BY. Las consultas que utilizan una función de agregación sin agrupar los resultados, como select count(*) from Movie, aún no son compatibles. Los campos que no son de agregación en la cláusula SELECT también deben aparecer en la cláusula GROUP BY.

El siguiente ejemplo agrupa las películas estrenadas entre 1920 y 1924 por año. Para cada año, devuelve el número de películas y la duración total de todas ellas. La cláusula HAVING incluye solo los años cuyas películas tienen una duración total superior a 300 minutos y ordena los resultados por año.

var aggregateResult = session.createQuery(
"select year, count(*), sum(runtime) from Movie where year between 1920 and 1924 "
+ "group by year having sum(runtime) > 300 order by year",
Object[].class)
.getResultList();
for (var row : aggregateResult) {
System.out.println("Year: " + row[0] + ", Count: " + row[1] + ", Total runtime: " + row[2]);
}
var aggregateResult = entityManager.createQuery(
"select m.year, count(m), sum(m.runtime) from Movie m where m.year between 1920 and 1924 "
+ "group by m.year having sum(m.runtime) > 300 order by m.year",
Object[].class)
.getResultList();
for (var row : aggregateResult) {
System.out.println("Year: " + row[0] + ", Count: " + row[1] + ", Total runtime: " + row[2]);
}

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 a realizar consultas entre entidades vinculadas por una asociación, consulte la guía "Unir entidades entre colecciones".

Para aprender cómo devolver parte de un valor de fecha y hora o cómo representar un valor de fecha y hora como una cadena, consulte la guía "Uso de funciones de fecha y hora en consultas".

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.

Califique esta página