Menu Docs
Página inicial do Docs
/ /

Tutorial: consultar o MongoDB com dados da Spring

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çãoda estrutura de dados do Spring.

Você deve ter os seguintes itens para concluir este tutorial:

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"
}
}
}

O aplicação neste tutorial é uma API REST 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 MongoTemplate para operações flexíveis.

1

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);
2

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.

@Query(
value= "{ 'status' : ?0 }",
fields="{ 'createdAt': 1, 'accountDetails' : 1, 'amount' : 1}",
sort = "{ createdAt: -1}"
)
List<Transaction> findByStatus(String status);

Os parâmetros na anotação @Query especificam o seguinte:

  • value especifica os critérios de filtro.

  • fields define quais campos incluir nos resultados.

  • sort ordena os resultados pelo valor do campo createdAt em ordem decrescente.

Para saber mais sobre a @Query anotação, consulte a documentação do Spring Data MongoDB .

3

A interface TransactionRepository inclui um método que combina as anotações @Query e @Update para atualizar o status de uma transação:

@Query("{ '_id' : ?0 }")
@Update("{ '$set' : { 'status' : ?1 } }")
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.

4

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:

@Aggregation(pipeline = {
"{ '$match': { 'transactionType': ?0 } }",
"{ '$group': { '_id': '$transactionType', 'amount': { '$sum': '$amount' } } }",
"{ '$project': { 'amount': 1 } }"
})
List<Transaction> getTotalAmountByTransactionType(String transactionType);

Esse pipeline de agregação executa as seguintes operações:

  • $match filtra transações por tipo.

  • $group agrupa transações por tipo e soma os valores.

  • $project exibe o valor total.

5

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:

@Aggregation(pipeline = {
"{ '$match': { 'status': 'error' } }",
"{ '$project': { '_id': 1, 'amount': 1, 'status': 1, 'description': 1, 'createdAt': 1} }",
"{ '$out': 'error_transactions' }"
})
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 $out estágio substitui a collection de destino se ela já existir.

6

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;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
@Aggregation(pipeline = {
"{ '$search': { 'text': { 'query': ?0, 'path': ?1 } } }"
})
@interface SearchAggregate {
}

A interface TransactionRepository inclui o seguinte código que usa a anotação:

@SearchAggregate
List<Transaction> search(String query, String path);
7

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:

@GetMapping("/pageable")
public PagedModel<Transaction> findAll(@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "100") int sizePerPage,
@RequestParam(defaultValue = "ID") String sortField,
@RequestParam(defaultValue = "DESC") Sort.Direction sortDirection) {
Pageable pageable = PageRequest.of(page, sizePerPage, Sort.by(sortDirection, sortField));
return new PagedModel<>(transactionService.findPageableTransactions(pageable));
}

Ligue para esse endpoint executando o seguinte comando no seu terminal enquanto o aplicação é executado:

curl --location 'http://localhost:8080/transactions?page=0&sizePerPage=10&sortField=description&sortDirection=ASC'
8

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 aggregations.

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;
@Configuration
public class MongoConfig {
@Bean
public MongoClient mongoClient() {
MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString("<your connection string>"))
.build();
return MongoClients.create(settings);
}
@Bean
MongoOperations mongoTemplate(MongoClient mongoClient) {
return new MongoTemplate(mongoClient, "springshop");
}
}
9

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
) {}
}
10

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.

11

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.

12

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.

13

Execute seu aplicação 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 aplicação é executado na porta 8080. Você pode testar suas queries enviando solicitações para os endpoints definidos nas etapas anteriores.

Para obter mais informações sobre como testar os endpoints nesse aplicação, consulte o README no repositório Spring-data-unlocked.

Para saber mais sobre o Spring Data MongoDB, consulte a documentação do Spring Data MongoDB .

Para saber mais sobre agregação pipelines, consulte Agregação no manual do MongoDB Server .

Voltar

Spring Data MongoDB