Docs Menu
Docs Home
/ /

튜토리얼: Spring 데이터로 MongoDB 쿼리하기

이 튜토리얼에서는 Spring Data를 사용하여 MongoDB 와 상호 작용 작용하여 고급 쿼리를 생성하는 방법을 보여줍니다. MongoRepository 인터페이스와 MongoTemplate 클래스를 사용하여 데이터 필터링, 업데이트, 애그리게이션 등의 작업을 수행하는 방법을 학습 .

참고

이 튜토리얼을 진행하려면 Spring Data와 MongoDB 에 대한 기본 지식이 필요합니다. MongoDB 에서 Spring Data를 사용하는 방법에 대한 소개는 Spring Data Framework Integration 튜토리얼을 참조하세요.

이 튜토리얼을 완료하려면 다음 항목이 있어야 합니다.

  • spring-data-unlocked 예시 리포지토리 의 소스 코드입니다. 리포지토리의 README 지침에 따라 프로젝트 설정하다 하고 실행 .

  • 무료 클러스터 가 있는MongoDB Atlas 계정. Atlas 계정 및 클러스터 를 만드는 방법을 학습 보려면 MongoDB 시작하기 가이드 참조하세요.

  • Java 21 이상.

  • Gradle 8.8 이상.

  • 선호하는 IDE.

이 튜토리얼에서는 다음과 같은 구조의 트랜잭션 데이터 모델 사용합니다.

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

이 튜토리얼의 애플리케이션 고객 기록과 트랜잭션을 관리하는 REST API 입니다.

이 튜토리얼에서는 다음 조치를 수행하는 방법을 보여줍니다.

  • MongoRepository을(를) 사용하여 파생 쿼리를 만듭니다.

  • @Query 주석을 사용하여 쿼리를 만듭니다.

  • @Update 주석을 사용하여 데이터를 업데이트합니다.

  • 집계 파이프라인 메서드를 검토합니다.

  • 페이지 매김을 구현합니다.

  • 유연한 작업을 위해 MongoTemplate 를 사용합니다.

1

spring-data-unlocked 프로젝트 의 src/main/java/com/mongodb/resources 디렉토리 로 이동하여 TransactionRepository 인터페이스를 엽니다. 이 인터페이스에는 유형별로 트랜잭션을 찾는 다음 메서드가 포함되어 있습니다.

List<Transaction> findByTransactionType(String type);

Spring Data는 메서드 이름을 사용하여 쿼리 생성합니다. findBy 접두사는 Spring Data에 쿼리 생성하도록 지시하고, TransactionType 는 필터하다 할 필드 지정합니다.

application.properties 파일 에 다음 줄을 추가하여 디버그 로깅을 활성화 생성된 쿼리를 볼 수 있습니다.

logging.level.org.springframework.data.mongodb=DEBUG

Spring Boot가 지정된 속성을 로드할 수 있도록 클래스 경로에 application.properties 파일 있는지 확인합니다.

findByTransactionType 쿼리 실행 하면 콘솔에 다음과 유사한 출력이 표시됩니다.

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

TransactionRepository 인터페이스에는 금액별로 트랜잭션을 찾고 유형별로 트랜잭션을 삭제 수 있는 다음 메서드도 포함되어 있습니다.

List<Transaction> findByAmountGreaterThan(double amount);
void deleteByTransactionType(String type);
2

TransactionRepository 은(는) @Query 주석을 사용하여 status 필드 값으로 트랜잭션을 찾는 findByStatus() 메서드를 정의합니다. 이 메서드는 특정 필드만 반환하고 결과를 정렬합니다.

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

@Query 주석의 매개변수는 다음을 지정합니다.

  • value 필터하다 기준을 지정합니다.

  • fields 결과에 포함할 필드를 정의합니다.

  • sort createdAt 필드 값을 기준으로 결과를 내림차순으로 정렬합니다.

@Query 주석에 대해 자세히 학습 Spring Data MongoDB 문서를 참조하세요.

3

TransactionRepository 인터페이스에는 @Query@Update 주석을 결합하여 트랜잭션 상태를 업데이트 하는 메서드가 포함되어 있습니다.

@Query("{ '_id' : ?0 }")
@Update("{ '$set' : { 'status' : ?1 } }")
void updateStatus(String id, String status);

@Query 주석은 ID 로 문서 찾고 @Update 주석은 상태 필드 수정합니다.

자세한 학습 은 업데이트 작업에 대한 Spring Data MongoDB 문서를 참조하세요.

4

TransactionRepository 인터페이스에는 @Aggregation 주석을 사용하여 트랜잭션 유형별로 그룹화된 총액을 계산하는 메서드가 포함되어 있습니다.

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

이 집계 파이프라인은 다음 작업을 수행합니다.

  • $match 유형별로 트랜잭션을 필터링합니다.

  • $group 트랜잭션을 유형별로 그룹화하고 금액을 합산합니다.

  • $project 총 금액을 표시합니다.

5

TransactionRepository 인터페이스에는 $out 단계를 사용하여 오류 트랜잭션을 새 컬렉션 에 복사하는 메서드도 포함되어 있습니다.

@Aggregation(pipeline = {
"{ '$match': { 'status': 'error' } }",
"{ '$project': { '_id': 1, 'amount': 1, 'status': 1, 'description': 1, 'createdAt': 1} }",
"{ '$out': 'error_transactions' }"
})
void exportErrorTransactions();

이 메서드를 호출하면 MongoDB error_transactions 라는 새 컬렉션 만들고 오류 상태인 모든 문서를 삽입합니다.

중요

프로덕션에서 이 단계를 사용하기 전에 $out 연산자 설명서를 검토하세요. $out 대상 컬렉션 대체합니다.

6

src/main/java/com/mongodb/resources 디렉토리 의 SearchAggregate.java 파일 에는 텍스트 검색 수행하는 사용자 지정 주석을 생성하는 다음 코드가 포함되어 있습니다.

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

TransactionRepository 인터페이스에는 주석을 사용하는 다음 코드가 포함되어 있습니다.

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

MongoRepository 인터페이스는 페이지 매김 지원 제공하는 PagingAndSortingRepository를 확장합니다. TransactionService 클래스를 열고 다음 메서드를 추가합니다.

public Page<Transaction> findPageableTransactions(
Pageable pageable
) {
return transactionRepository.findAll(pageable);
}

src/main/java/com/mongodb/application/web 디렉토리 의 TransactionController 클래스에는 페이지 매김 매개변수를 허용하는 다음 컨트롤러 메서드가 포함되어 있습니다.

@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));
}

애플리케이션 이 실행되는 동안 터미널에서 다음 명령을 실행 하여 이 엔드포인트를 호출합니다.

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

MongoTemplate 클래스는 MongoDB 에서 작업을 수행하는 데 MongoRepository 보다 더 많은 유연성을 제공합니다. 다음 단계에서는 MongoTemplate 를 사용하여 대량 작업, 쿼리 및 애그리게이션을 수행하는 방법을 학습 .

src/main/java/com/mongodb/resources 디렉토리 로 이동하여 MongoTemplate를 설정하는 MongoConfig.java이라는 구성 클래스를 확인합니다.

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

src/main/java/com/mongodb/model 디렉토리 의 Customer.java 파일 다음 기록 정의합니다.

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

src/main/java/com/mongodb/domain/service 디렉토리 의 CustomerService 클래스에는 여러 문서를 한 번에 삽입하는 다음 메서드가 포함되어 있습니다.

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

bulkOps 메서드는 목록에 있는 모든 문서를 삽입하는 대량 작업을 생성합니다.

11

CustomerService 클래스에는 이메일 로 고객을 찾는 메서드가 포함되어 있습니다.

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

query 메서드는 필터하다 정의하는 Criteria 객체 허용합니다. gt(), lt(), and(), or() 등의 메서드를 사용하여 복잡한 쿼리를 빌드 수 있습니다.

자세한 학습 은 Criteria(기준) 클래스 설명서를 참조하세요.

12

src/main/java/com/mongodb/domain/model 디렉토리 의 CustomersByCity 클래스에는 집계 결과를 보관하는 다음 기록 포함되어 있습니다.

public record CustomersByCity(
String id,
int total
){}

CustomerService.java 파일 도시별로 고객 수를 계산하는 메서드가 포함되어 있습니다.

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();
}

이 방법은 고객을 도시별로 그룹화하고 각 도시의 고객 수를 계산합니다.

13

IDE에서 SpringShopApplication 클래스를 실행 하거나 터미널에서 다음 명령을 실행 하여 애플리케이션 실행합니다.

export MONGODB_URI="<YOUR_CONNECTION_STRING>"
./gradlew bootRun

애플리케이션 이 포트 8080에서 실행됩니다. 이전 단계에서 정의된 엔드포인트에 요청을 전송하여 쿼리를 테스트할 수 있습니다.

이 애플리케이션 에서 엔드포인트를 테스트하는 방법에 대한 자세한 내용은 Spring-data-unlocked 리포지토리 의 README를 참조하세요.

Spring Data MongoDB 에 대해 자세히 학습 Spring Data MongoDB 문서를 참조하세요.

집계 파이프라인에 대해 자세히 학습 MongoDB Server 매뉴얼에서 애그리게이션을 참조하세요.

돌아가기

Spring Data MongoDB