Overview
En esta guía, aprenderá a usar la extensión MongoDB para Hibernate ORM y ejecutar consultas nativas en su base de datos MongoDB. En lugar de Hibernate Query Language (HQL) o Jakarta Persistence Query Language (JPQL), las consultas nativas le permiten usar MongoDB Query Language (MQL) para especificar su consulta. MQL es una sintaxis de consulta diseñada para interactuar con el modelo basado en documentos de MongoDB.
Tip
MongoDB languaje del query
Para obtener más información sobre la sintaxis y la funcionalidad de MQL, consulte la Referencia del lenguaje de consulta de MongoDB en el manual del servidor de MongoDB.
El método createQuery() de Hibernate ORM no es compatible con algunas funciones de query de MongoDB. El método createNativeQuery() te permite especificar consultas de base de datos en MQL y sortear algunas limitaciones operativas de la extensión Hibernate ORM.
También puedes ejecutar consultas directamente en tu objeto MongoClient para una funcionalidad de consulta ampliada.
Datos de muestra
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.util.List; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; public class Movie { private ObjectId id; private String title; private String plot; private int year; private int runtime; private List<String> cast; private List<String> directors; public Movie(String title, String plot, int year, int runtime, List<String> cast, List<String> directors) { this.title = title; this.plot = plot; this.year = year; this.runtime = runtime; this.cast = cast; this.directors = directors; } 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 int getRuntime() { return runtime; } public void setRuntime(int runtime) { this.runtime = runtime; } 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; } }
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.
Nota
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 una Session de Hibernate o una EntityManager de Jakarta Persistence. Los ejemplos de esta guía utilizan un Session. Para obtener más información sobre los contextos de persistencia, consulte la guía Transacciones y sesiones.
Ejecuta consultas nativas
Para ejecutar un query nativo de MongoDB, especifica una instrucción del languaje del query de MongoDB (MQL) que incluya la colección a consultar y tus criterios de query en un pipeline de agregación.
Tip
Pipeline de agregación
Para obtener más información sobre cómo construir pipelines de agregación y ejecutar operaciones de agregación, consulta la referencia sobre pipeline de agregación en el manual de MongoDB Server.
Las instrucciones MQL tienen el siguiente formato:
String mqlSyntax = """ { aggregate: "<collection to query>", pipeline: [ <aggregation pipeline stages> ] } """;
Importante
$project Requisitos de la etapa
La canalización de agregación en su instrucción MQL debe incluir una etapa $project. Para devolver los documentos de consulta como instancias de entidad, debe especificar cada campo de entidad en la etapa $project, incluido el campo _id. La extensión Hibernate ORM devuelve los campos que proyecta y suprime _id cuando lo omite. Una consulta vinculada a una entidad que omite _id puede fallar con Unknown column label [_id] porque el identificador de entidad se asigna a _id. Para mantener el identificador disponible, proyecte _id: 1.
Luego, pase la instrucción MQL al método createNativeQuery().
Puedes utilizar consultas nativas para realizar las siguientes operaciones:
Importante
Se requiere sintaxis JSON extendida.
Debe escribir consultas nativas en formato JSON extendido v2. La extensión Hibernate ORM no admite comillas simples ni la sintaxis de expresiones regulares del shell del servidor MongoDB (/pattern/) en las consultas nativas. Por ejemplo, para consultar con una expresión regular, utilice el tipo JSON extendido $regularExpression en lugar de /pattern/.
Filtrar y organizar campos del documento
Este ejemplo ejecuta una consulta nativa en la colección sample_mflix.movies pasando una instrucción MQL al método createNativeQuery(). El código especifica las siguientes etapas del pipeline de agregación:
$matchFiltros para documentos que tienen un valor de campo de título"The Parent Trap"$sort: Ordena los documentos coincidentes por sus camposyearen orden descendente$projectDevuelve cada campo de documento definido en la entidadMovie
String nativeQuery = """ { aggregate: "movies", pipeline: [ { $match: { title: { $eq: "The Parent Trap" } } }, { $sort: { year: -1 } }, { $project: { _id: 1, title: 1, plot: 1, year: 1, runtime: 1, cast: 1 } } ] } """; var results = session.createNativeQuery(nativeQuery, Movie.class) .getResultList(); for (Movie movie : results) { System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear()); }
Usa operadores aritméticos
Nota
Las consultas nativas son la mejor opción para operaciones aritméticas que no son compatibles con la extensión Hibernate ORM. Para obtener más información sobre los operadores aritméticos compatibles con la extensión Hibernate ORM, consulte la sección «Compatibilidad con consultas» de la página «Compatibilidad de funciones».
El siguiente ejemplo ejecuta una query nativa en la colección sample_mflix.movies que realiza las siguientes acciones:
Especifica una etapa
$matchpara hacer coincidir los documentos que tienen un valoryearmayor que2000y un camporuntimeque existeEspecifica una etapa
$addFieldspara agregar un nuevo campo llamadoruntimeHoursUtiliza el operador aritmético
$dividepara convertir el valorruntimede minutos a horas para el nuevo camporuntimeHoursEspecifica una etapa
$projectpara devolver cada campo del documento definido en la entidadMovie, incluido el campo_id.Imprime el valor
titlede cada documento actualizado
String nativeQuery = """ { aggregate: "movies", pipeline: [ { $match: { year: { $gt: 2000 }, runtime: { $exists: true } } }, { $addFields: { runtimeHours: { $divide: [ "$runtime", 60 ] } }}, { $project: { _id: 1, title: 1, plot: 1, year: 1, runtime: 1, cast: 1, runtimeHours: 1 }} ] } """; var results = session.createNativeQuery(nativeQuery, Movie.class) .getResultList(); for (Movie result : results) { System.out.println("Added field to movie: " + result.getTitle()); }
Tip
Operadores aritméticos
Para obtener más información sobre los operadores aritméticos de Hibernate y MongoDB, consulta los siguientes recursos:
Aritmética numérica en la guía de query Hibernate ORM
Operadores aritméticos en el manual del servidor MongoDB
Ejecuta una MongoDB Search query
Puedes ejecutar queries nativas para realizar queries de búsqueda de MongoDB en tu base de datos, que son búsquedas de texto detalladas en tus datos. Estas consultas proporcionan funcionalidades avanzadas de búsqueda, tales como la coincidencia de frases de texto, la puntuación de resultados por relevancia y el resaltado de coincidencias.
Importante
No puedes ejecutar una consulta MongoDB Search dentro de una transacción.
Para especificar una consulta de búsqueda, crea un índice de búsqueda que abarque los campos que deseas consultar. Luego, pasa un pipeline de agregación a tu método createNativeQuery() que incluya una etapa $search o $searchMeta.
Tip
MongoDB búsqueda
Para obtener más información sobre las consultas e índices de MongoDB Search, consulte Descripción general de MongoDB Search en el manual del servidor de MongoDB.
Este ejemplo ejecuta una consulta de búsqueda pasando la etapa de pipeline $search al método createNativeQuery(). El código realiza las siguientes acciones:
Especifica el índice de búsqueda que abarca el campo
plot. Asegúrate de reemplazar el marcador de posición<indexName>por el nombre de tu índice de búsqueda.Queries para documentos cuyos valores de
plotcontienen la string"whirlwind romance"con no más de3palabras entre ellosEspecifica una etapa
$projectpara devolver cada campo del documento definido en la entidadMovie, incluido el campo_id.Imprime los valores de
titleyplotde los documentos coincidentes
String nativeQuery = """ { aggregate: "movies", pipeline: [ { $search: { index: "<indexName>", phrase: { path: "plot", query: "whirlwind romance", slop: 3 } } }, { $project: { _id: 1, title: 1, plot: 1, year: 1, runtime: 1, cast: 1 } } ] } """; var results = session.createNativeQuery(nativeQuery, Movie.class) .getResultList(); for (Movie result : results) { System.out.println("Title: " + result.getTitle() + ", Plot: " + result.getPlot()); }
Usar parámetros en consultas nativas
Puede utilizar parámetros con nombre (:name) u ordinales (?1) para especificar valores en su instrucción MQL. El siguiente ejemplo muestra cómo proporcionar el valor del parámetro title como un parámetro con nombre u ordinal y, a continuación, suministrar el valor del parámetro con setParameter():
String nativeQuery = """ { aggregate: "movies", pipeline: [ { $match: { title: { $eq: :movieTitle } } }, { $sort: { year: -1 } }, { $project: { _id: 1, title: 1, plot: 1, year: 1, runtime: 1, cast: 1 } } ] } """; var results = session.createNativeQuery(nativeQuery, Movie.class) .setParameter("movieTitle", "The Parent Trap") .getResultList(); for (Movie movie : results) { System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear()); }
String nativeQuery = """ { aggregate: "movies", pipeline: [ { $match: { title: { $eq: ?1 } } }, { $sort: { year: -1 } }, { $project: { _id: 1, title: 1, plot: 1, year: 1, runtime: 1, cast: 1 } } ] } """; var results = session.createNativeQuery(nativeQuery, Movie.class) .setParameter(1, "The Parent Trap") .getResultList(); for (Movie movie : results) { System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear()); }
Ejecute operaciones de MongoClient
Si quieres ejecutar operaciones de base de datos que no sean compatibles ni con el método createQuery() ni con el método createNativeQuery(), puedes operar directamente sobre un objeto MongoClient en tu aplicación Java. Al trabajar con MongoClient, puedes acceder a la funcionalidad del MongoDB Java Sync Driver.
Tip
Compatibilidad de funcionalidad
Para obtener más información sobre las funcionalidades no compatibles de MongoDB a las que debes acceder utilizando un objeto MongoClient, consulta la página Compatibilidad de funcionalidad.
Para aprender a usar el controlador Java para interactuar con MongoDB, revise la documentación del controlador Java de MongoDB.
Crear índices con el MongoClient
No se puede usar la extensión Hibernate ORM para crear índices en una colección, pero se puede instanciar un MongoClient y usar el método createIndex() del driver de Java. El siguiente código crea un índice de campo title en la colección sample_mflix.movies:
// Replace the <connection URI> placeholder with your MongoDB connection URI String uri = "<connection URI>"; MongoClient mongoClient = MongoClients.create(uri); MongoDatabase db = mongoClient.getDatabase("sample_mflix"); MongoCollection<Document> collection = db.getCollection("movies"); String indexResult = collection.createIndex(Indexes.ascending("title")); System.out.println(String.format("Index created: %s", indexResult));
Para obtener más información sobre cómo utilizar el driver de Java para crear índices, consulta la guía Índices en la documentación del driver de Java.
Información Adicional
Para aprender más sobre los languajes de los query tratados en esta guía, consulte los siguientes recursos:
Una guía rápida del languaje del query de Hibernate en la documentación de Hibernate ORM
Referencia del Lenguaje de Consulta de MongoDB en el manual del MongoDB Server