Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Menu Docs
Página inicial do Docs
/ /

Tutorial: query 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ção do Spring Data Framework.

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.

  • Java 21 ou posterior.

  • Gradle 8.8 ou posterior.

  • Seu IDE preferido.

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 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 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 anotação @Query, 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 estágio $out substitui a coleção 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));
}

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'
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 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;
@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 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.

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.

Voltar

Spring Data MongoDB