Overview
En este tutorial se muestra cómo crear advanced queries utilizando Spring Data para interactuar con MongoDB. Aprendes a utilizar el
MongoRepository la interfaz y la clase MongoTemplate para realizar operaciones como filtrar, actualizar y agregar datos.
Nota
Este tutorial requiere una comprensión básica de Spring Data y MongoDB. Para una introducción al uso de Spring Data con MongoDB, consulta la Tutorial de integración del marco Spring Data.
Requisitos previos
Debe contar con los siguientes elementos para completar este tutorial:
Código fuente de la spring-data-unlocked repositorio de ejemplo. Siga las instrucciones del archivo README del repositorio para configurar y ejecutar el proyecto.
cuenta de MongoDB Atlas con un clúster gratuito. Para aprender a crear una cuenta y clúster de Atlas, consulta la guía Introducción a MongoDB.
Tu IDE preferido.
modelo de datos
Este tutorial utiliza un modelo de datos de transacciones que tiene la siguiente estructura:
{ "id": "672182814338f60133ee26e1", "transactionType": "Debit", "amount": 888.0, "currency": "USD", "status": "In Progress", "description": "Transfer to Ricardo", "createdAt": "2024-10-09T14:00:00", "accountDetails": { "originator": { "accountNumber": "2376543213", "name": "Maria", "bank": "Bank G" }, "beneficiary": { "accountNumber": "2234987651", "name": "Ricardo Mello", "bank": "Bank V" } } }
Tutorial
La aplicación en este tutorial es una REST API que gestiona registros de clientes y transacciones.
Este tutorial te muestra cómo realizar las siguientes acciones:
Crea consultas derivadas usando
MongoRepository.Crea consultas con la anotación
@Query.Actualice los datos utilizando la anotación
@Update.Revise los métodos del pipeline de agregación.
Implementar paginación.
Utiliza
MongoTemplatepara operaciones flexibles.
Crea consultas derivadas usando MongoRepository.
Navegue hasta el directorio src/main/java/com/mongodb/resources en el proyecto spring-data-unlocked y abra la interfaz TransactionRepository. Esta interfaz incluye el siguiente método para encontrar transacciones por tipo:
List<Transaction> findByTransactionType(String type);
Spring Data utiliza el nombre del método para crear una query. El prefijo findBy indica a Spring Data que cree una query y TransactionType especifica el campo para filtrar.
Puede activar el registro de depuración para ver las consultas generadas añadiendo la siguiente línea a su archivo application.properties:
logging.level.org.springframework.data.mongodb=DEBUG
Tip
Asegúrate de que el archivo application.properties esté en tu classpath para que Spring Boot pueda cargar las propiedades especificadas.
Cuando ejecute la consulta findByTransactionType, la consola mostrará una salida similar a la siguiente:
2024-10-15T18:30:33.855-03:00 DEBUG 28992 [SpringShop] [nio-8080-exec-6] o.s.data.mongodb.core.MongoTemplate: find using query: { "transactionType" : "Transfer"} fields: Document{{}} sort: { "transactionType" : "Transfer"} for class: class com.mongodb.Transaction in collection: transactions
La interfaz TransactionRepository también incluye los siguientes métodos para encontrar transacciones por monto y borrar transacciones por tipo:
List<Transaction> findByAmountGreaterThan(double amount); void deleteByTransactionType(String type);
Crear consultas usando la anotación @Query.
El TransactionRepository define el método findByStatus() que utiliza la anotación @Query para buscar transacciones por su valor de campo status. Este método sólo devuelve campos específicos y ordena los resultados.
List<Transaction> findByStatus(String status);
Los parámetros en la @Query anotación especifican lo siguiente:
valueespecifica los criterios de filtro.fieldsdefine qué campos incluir en los resultados.sortordena los resultados por el valor del campocreatedAten orden descendente.
Para saber más sobre la anotación @Query, consulta la documentación Spring Data MongoDB.
Actualiza los datos mediante la anotación @Update.
La interfaz TransactionRepository incluye un método que combina las anotaciones @Query y @Update para actualizar el estado de una transacción:
void updateStatus(String id, String status);
La anotación @Query encuentra el documento por ID y la anotación @Update modifica el campo de estado.
Para obtener más información, consulta la documentación de Spring Data MongoDB sobre operaciones de actualización.
Revise los métodos del pipeline de agregación.
La interfaz TransactionRepository incluye un método que utiliza la anotación @Aggregation para calcular el monto total agrupado por tipo de transacción:
List<Transaction> getTotalAmountByTransactionType(String transactionType);
Esta pipeline de agregación realiza las siguientes operaciones:
$matchfiltra las transacciones por tipo.$groupagrupa las transacciones por tipo y suma los importes.$projectmuestra el importe total.
Exporta transacciones de error a una nueva colección.
La interfaz TransactionRepository también incluye un método que utiliza la etapa $out para copiar transacciones erróneas a una nueva colección:
void exportErrorTransactions();
Al llamar a este método, MongoDB crea una nueva colección llamada error_transactions e inserta todos los documentos con un estado de error.
Importante
Revise la documentación del operador $out antes de usar esta etapa en producción. La etapa $out reemplaza la colección de destino si ya existe.
Revisa la anotación de búsqueda de texto.
El archivo SearchAggregate.java en el directorio src/main/java/com/mongodb/resources incluye el siguiente código que crea una anotación personalizada que realiza una búsqueda de texto.
import org.springframework.data.mongodb.repository.Aggregation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; SearchAggregate { }
La interfaz de TransactionRepository incluye el siguiente código que utiliza la anotación:
List<Transaction> search(String query, String path);
Implementar paginación.
La interfaz MongoRepository extiende PagingAndSortingRepository, la cual brinda soporte de paginación. Abre tu TransactionService clase y añade el siguiente método:
public Page<Transaction> findPageableTransactions( Pageable pageable ) { return transactionRepository.findAll(pageable); }
La clase TransactionController en el directorio src/main/java/com/mongodb/application/web incluye el siguiente método de controlador que acepta parámetros de paginación:
public PagedModel<Transaction> findAll( int page, int sizePerPage, String sortField, Sort.Direction sortDirection) { Pageable pageable = PageRequest.of(page, sizePerPage, Sort.by(sortDirection, sortField)); return new PagedModel<>(transactionService.findPageableTransactions(pageable)); }
Llama a este endpoint ejecutando el siguiente comando desde tu terminal mientras la aplicación esté ejecutándose:
curl --location 'http://localhost:8080/transactions?page=0&sizePerPage=10&sortField=description&sortDirection=ASC'
Configura MongoTemplate.
La clase MongoTemplate proporciona más flexibilidad que MongoRepository para realizar operaciones en MongoDB. En los siguientes pasos, aprenderá a usar MongoTemplate para realizar operaciones, consultas y agregaciones masivas.
Navega al directorio src/main/java/com/mongodb/resources para ver la clase de configuración llamada MongoConfig.java, que configura MongoTemplate:
package com.mongodb; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.MongoTemplate; public class MongoConfig { public MongoClient mongoClient() { MongoClientSettings settings = MongoClientSettings.builder() .applyConnectionString(new ConnectionString("<your connection string>")) .build(); return MongoClients.create(settings); } MongoOperations mongoTemplate(MongoClient mongoClient) { return new MongoTemplate(mongoClient, "springshop"); } }
Revisa el modelo cliente.
El archivo Customer.java en el directorio src/main/java/com/mongodb/model define el siguiente registro:
package com.mongodb.model; public record Customer( String name, String email, String accountNumber, String phone, Address address ) { public record Address( String street, String city ) {} }
Realiza operaciones de inserción masiva.
La clase CustomerService en el directorio src/main/java/com/mongodb/domain/service incluye el siguiente método que inserta varios documentos al mismo tiempo:
public int bulkCustomerSample(List<Customer> customerList) { if (findAll().isEmpty()) { BulkWriteResult result = mongoOperations.bulkOps(BulkOperations.BulkMode.ORDERED, Customer.class) .insert(customerList) .execute(); return result.getInsertedCount(); } return 0; }
El método bulkOps crea una operación masiva que inserta todos los documentos en la lista.
query documentos con MongoTemplate.
La clase CustomerService incluye un método que busca un cliente por correo electrónico:
public Customer findCustomerByEmail(String email) { return mongoOperations.query(Customer.class) .matching(query(where("email").is(email))) .one() .orElseThrow(() -> new RuntimeException("Customer not found with email: " + email)); }
El método query acepta un objeto Criteria que define el filtro. Puedes usar métodos como gt(), lt(), and() y or() para compilar consultas complejas.
Para obtener más información, consulta la documentación de la clase Criteria.
Realice agregaciones con MongoTemplate.
La clase CustomersByCity en el directorio src/main/java/com/mongodb/domain/model contiene el siguiente registro que retiene los resultados de agregación:
public record CustomersByCity( String id, int total ){}
El archivo CustomerService.java incluye un método que cuenta clientes por ciudad:
public List<CustomersByCity> totalCustomerByCity() { TypedAggregation<Customer> aggregation = newAggregation(Customer.class, group("address.city") .count().as("total"), Aggregation.sort(Sort.Direction.ASC, "_id"), project(Fields.fields("total", "_id"))); AggregationResults<CustomersByCity> result = mongoOperations.aggregate(aggregation, CustomersByCity.class); return result.getMappedResults(); }
Este método agrupa a los clientes por ciudad y cuenta el número de clientes en cada ciudad.
Prueba tus consultas.
Ejecuta tu aplicación ejecutando la clase SpringShopApplication en tu IDE o ejecutando los siguientes comandos desde tu terminal:
export MONGODB_URI="<YOUR_CONNECTION_STRING>" ./gradlew bootRun
La aplicación se ejecuta en el puerto 8080. Puedes probar tus consultas enviando solicitudes a los endpoints definidos en los pasos anteriores.
Para obtener más información sobre cómo probar los endpoints en esta aplicación, consulte el archivo README en el repositorio spring-data-unlocked.
Recursos adicionales
Para obtener más información sobre Spring Data MongoDB, consulta la documentación de Spring Data MongoDB.
Para obtener más información sobre los pipelines de agregación, consulta Agregación en el Manual de MongoDB Server.