Visão geral
Este tutorial mostra como criar queries avançadas usando dados da Spring para interagir com o MongoDB. Você aprenderá a usar a interface MongoRepository e a classe MongoTemplate para executar operações como filtragem, atualização e agregação de dados.
Observação
Este tutorial requer uma compreensão básica de Spring Data e MongoDB. Para obter uma introdução sobre como usar o Spring Data com MongoDB, consulte o tutorial Integração do Spring Data Framework.
Pré-requisitos
Você deve ter os seguintes itens para concluir este tutorial:
Código fonte do repositório de exemplo Spring-data-unlocked. Siga as instruções no README do repositório para configurar e executar o projeto.
Conta doMongoDB Atlas com um cluster gratuito. Para saber como criar uma conta e um cluster do Atlas, consulte o guia de Introdução ao MongoDB.
Seu IDE preferido.
Modelo de dados
Este tutorial utiliza um modelo de dados de transação que tem a seguinte estrutura:
{ "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
O aplicativo neste tutorial é uma REST API que gerencia registros e transações de cliente.
Este tutorial mostra como executar as seguintes ações:
Criar consultas derivadas utilizando
MongoRepository.Crie consultas utilizando a anotação
@Query.Atualize os dados usando a anotação
@Update.Revise os métodos de pipeline de agregação .
Implemente a paginação.
Use o
MongoTemplatepara operações flexíveis.
Crie queries derivadas usando MongoRepository.
Navegue até o diretório src/main/java/com/mongodb/resources no projeto spring-data-unlocked e abra a interface do TransactionRepository. Essa interface inclui o seguinte método para encontrar transações por tipo:
List<Transaction> findByTransactionType(String type);
O Spring Data usa o nome do método para criar uma query. O prefixo findBy instrui a Spring Data a criar uma query e TransactionType especifica o campo no qual filtrar.
Você pode habilitar o log de depuração para ver as queries geradas adicionando a seguinte linha ao seu arquivo application.properties:
logging.level.org.springframework.data.mongodb=DEBUG
Dica
Certifique-se de que o arquivo application.properties esteja em seu classpath para que o Spring Boot possa carregar as propriedades especificadas.
Quando você executa a query do findByTransactionType, o console exibe saída semelhante ao seguinte:
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
A interface TransactionRepository também inclui os seguintes métodos para localizar transações por valor e excluir transações por tipo:
List<Transaction> findByAmountGreaterThan(double amount); void deleteByTransactionType(String type);
Crie queries usando a anotação @Query.
O TransactionRepository define um método findByStatus() que utiliza a anotação @Query para localizar transações pelo seu valor de campo status. Este método retorna apenas campos específicos e classifica os resultados.
List<Transaction> findByStatus(String status);
Os parâmetros na anotação @Query especificam o seguinte:
valueespecifica os critérios de filtro.fieldsdefine quais campos incluir nos resultados.sortordena os resultados pelo valor do campocreatedAtem ordem decrescente.
Para saber mais sobre a anotação @Query, consulte a documentação do Spring Data MongoDB.
Atualize os dados usando a anotação @Update.
A interface TransactionRepository inclui um método que combina as anotações @Query e @Update para atualizar o status de uma transação:
void updateStatus(String id, String status);
A anotação @Query localiza o documento por ID e a anotação @Update modifica o campo de status.
Para saber mais, consulte a documentação do Spring Data MongoDB sobre operações de atualização.
Revise os métodos de pipeline de agregação .
A interface do TransactionRepository inclui um método que utiliza a anotação do @Aggregation para calcular o valor total agrupado por tipo de transação:
List<Transaction> getTotalAmountByTransactionType(String transactionType);
Esse pipeline de agregação executa as seguintes operações:
$matchfiltra transações por tipo.$groupagrupa transações por tipo e soma os valores.$projectexibe o valor total.
Exporte transações de erro para uma nova coleção.
A interface TransactionRepository também inclui um método que usa o estágio $out para copiar transações de erro para uma nova coleção:
void exportErrorTransactions();
Quando você chama esse método, o MongoDB cria uma nova coleção chamada error_transactions e insere todos os documentos que têm um status de erro.
Importante
Revise a documentação do operador $out antes de usar esse estágio da produção. O estágio $out substitui a coleção de destino se ela já existir.
Revise a anotação de pesquisa de texto.
O arquivo SearchAggregate.java no diretório src/main/java/com/mongodb/resources inclui o seguinte código que cria uma anotação personalizada que executa uma pesquisa 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 { }
A interface TransactionRepository inclui o seguinte código que usa a anotação:
List<Transaction> search(String query, String path);
Implemente a paginação.
A interface do MongoRepository estende o PagingAndSortingRepository, que fornece suporte de paginação. Abra sua classe TransactionService e adicione o seguinte método:
public Page<Transaction> findPageableTransactions( Pageable pageable ) { return transactionRepository.findAll(pageable); }
A classe TransactionController no diretório src/main/java/com/mongodb/application/web inclui o seguinte método de controlador que aceita parâmetros de paginação:
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)); }
Chame este ponto de extremidade executando o seguinte comando no seu terminal enquanto o aplicativo é executado:
curl --location 'http://localhost:8080/transactions?page=0&sizePerPage=10&sortField=description&sortDirection=ASC'
Configure o MongoTemplate.
A classe MongoTemplate oferece mais flexibilidade do que MongoRepository para executar operações no MongoDB. Nas etapas a seguir, você aprenderá como usar o MongoTemplate para executar operações em massa, queries e agregações.
Navegue até o diretório src/main/java/com/mongodb/resources para visualizar a classe de configuração denominada MongoConfig.java, que define o 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"); } }
Revise o modelo de cliente.
O arquivo Customer.java no diretório src/main/java/com/mongodb/model define o seguinte 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 ) {} }
Realize operações de inserção em massa.
A classe CustomerService no diretório src/main/java/com/mongodb/domain/service inclui o seguinte método que insere vários documentos de uma só 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; }
O método bulkOps cria uma operação em massa que insere todos os documentos na lista.
Fazer query de documentos com MongoTemplate.
A classe CustomerService inclui um método que encontra um cliente por e-mail:
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)); }
O método query aceita um objeto Criteria que define o filtro. Você pode utilizar métodos como gt(), lt(), and() e or() para construir consultas complexas.
Para saber mais, consulte a documentação da classe Critérios.
Realize agregações com MongoTemplate.
A classe CustomersByCity no diretório src/main/java/com/mongodb/domain/model contém o seguinte registro que contém os resultados da agregação :
public record CustomersByCity( String id, int total ){}
O arquivo CustomerService.java inclui um método que conta os clientes por cidade:
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(); }
Esse método agrupa clientes por cidade e conta o número de clientes em cada cidade.
Teste suas queries.
Execute seu aplicativo executando a classe SpringShopApplication em seu IDE ou executando os seguintes comandos a partir do seu terminal:
export MONGODB_URI="<YOUR_CONNECTION_STRING>" ./gradlew bootRun
O aplicativo é executado na porta 8080. Você pode testar suas queries enviando solicitações para os pontos de extremidade definidos nas etapas anteriores.
Para obter mais informações sobre como testar os pontos de extremidade nessa aplicativo, consulte o README no repositório spring-data-unlocked.
Recursos adicionais
Para aprender mais sobre o Spring Data MongoDB, consulte a documentação do Spring Data MongoDB.
Para saber mais sobre pipelines de agregação, consulte Agregação no manual do MongoDB Server.