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 datos de primavera desbloqueados 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 de este tutorial es una API REST que administra registros y transacciones de clientes.
Este tutorial te muestra cómo realizar las siguientes acciones:
Crea consultas derivadas usando
MongoRepository.Cree consultas utilizando la anotación
@Query.Actualice los datos utilizando la anotación
@Update.Revisar los métodos de canalización 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 habilitar el registro de depuración para ver las consultas generadas agregando 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);
Cree consultas utilizando 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 anotación @Query 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 obtener más información sobre la @Query anotación, consulte la documentación de 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.
Revisar los métodos de canalización 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 canalización 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.
Exportar transacciones erróneas 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)); }
Llame a este punto final ejecutando el siguiente comando desde su terminal mientras se ejecuta su aplicación:
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 ) {} }
Realizar 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 a la vez:
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 encuentra 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 los 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, consulte 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.