Overview
このチュートリアルでは、spring Data を使用してMongoDBと連携し、高度なクエリを作成する方法について説明します。 MongoRepositoryインターフェースと MongoTemplateクラスを使用して、データのフィルタリング、アップデート、集計などの操作を実行する方法を学習します。
注意
このチュートリアルでは、spring Data とMongoDBの基本を理解する必要があります。 MongoDBでspring Data を使用する方法の概要については、「 spring Data Framework 統合 」のチュートリアルを参照してください。
前提条件
Atlas の サンプル データ セット からの映画データを含むコレクションを使用します。
spring-data-unlocked 例リポジトリからのソースコード。リポジトリの README の指示に従って、プロジェクトをセットアップして実行します。
無料クラスターを持つMongoDB Atlasアカウント。 Atlas のアカウントとクラスターの作成方法については、 「 MongoDB の使用開始 」ガイドを参照してください。
ご希望の 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" } } }
Tutorial
このチュートリアルのアプリケーションは、カスタマーレコードとトランザクションを管理するREST APIです。
このチュートリアルでは、次のアクションを実行する方法について説明します。
MongoRepositoryを使用して派生クエリを作成します。@Queryアノテーションを使用してクエリを作成します。@Updateアノテーションを使用してデータをアップデートします。集計パイプラインメソッドを確認します。
ページネーションを実装します。
柔軟な操作には
MongoTemplateを使用します。
MongoRepository を使用して派生したクエリを作成します。
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
Tip
指定されたプロパティを読み込むには、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);
@Query アノテーションを使用してクエリを作成します。
TransactionRepository は、@Query アノテーションを使用して statusフィールド値でトランザクションを検索する findByStatus() メソッドを定義します。このメソッドは特定のフィールドのみを返し、結果をソートします。
List<Transaction> findByStatus(String status);
@Query アノテーションのパラメータは以下を指定します。
valueは、フィルター条件を指定します。fields結果に含めるフィールドを定義します。sortは、createdAtフィールド値の降順で結果を並べ替えます。
集計パイプラインメソッドを確認します。
TransactionRepository インターフェースには、@Aggregation アノテーションを使用してトランザクションタイプごとにグループ化された合計金額を計算するメソッドが含まれています。
List<Transaction> getTotalAmountByTransactionType(String transactionType);
この集計パイプラインは、次の操作を実行します。
$matchトランザクションをタイプ別にフィルタリングします。$groupトランザクションをタイプ別にグループ化し、金額を合計します。$project合計金額を表示。
エラー トランザクションを新しいコレクションにエクスポートします。
TransactionRepository インターフェースには、$out ステージを使用してエラー トランザクションを新しいコレクションにコピーするメソッドも含まれています。
void exportErrorTransactions();
このメソッドを呼び出すと、 MongoDB はerror_transactions という新しいコレクションを作成し、エラー ステータスを持つすべてのドキュメントを挿入します。
重要
このステージを本番環境で使用する前に、 $out 演算子のドキュメントを確認してください。$out ステージは、ターゲットコレクションがすでに存在する場合はそれを置き換えます。
テキスト検索の注釈を確認します。
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; SearchAggregate { }
TransactionRepository インターフェースには、 アノテーションを使用する次のコードが含まれています。
List<Transaction> search(String query, String path);
ページネーションを実装します。
MongoRepository インターフェースは PagingAndSortingRepository を拡張し、ページ分割をサポートします。 TransactionServiceクラスを開き、次のメソッドを追加します。
public Page<Transaction> findPageableTransactions( Pageable pageable ) { return transactionRepository.findAll(pageable); }
src/main/java/com/mongodb/application/webディレクトリ内の TransactionControllerクラスには、ページ分割パラメータを受け入れる次のコントローラー メソッドが含まれています。
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)); }
アプリケーションの実行中にターミナルから次のコマンドを実行中て、このエンドポイントを呼び出します。
curl --location 'http://localhost:8080/transactions?page=0&sizePerPage=10&sortField=description&sortDirection=ASC'
MongoTemplate を構成します。
MongoTemplateクラスは、 MongoDBで操作を実行する際、MongoRepository よりも柔軟性が高くなります。次の手順では、MongoTemplate を使用して一括操作、クエリ、集計を実行する方法を説明します。
src/main/java/com/mongodb/resourcesディレクトリに移動して、MongoConfig.java という名前の構成クラスを表示します。これは 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"); } }
一括挿入操作の実行。
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 メソッドは、すべてのドキュメントをリストに挿入する一括操作を作成します。
MongoTemplate でドキュメントをクエリします。
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クラスのドキュメントを参照してください。
MongoTemplate を使用して集計を実行します。
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(); }
このメソッドは、カスタマーを都市別にグループ化し、各都市のカスタマー数をカウントします。
クエリをテストします。
アプリケーションを実行するには、IDE で SpringShopApplicationクラスを実行中か、ターミナルから次のコマンドを実行中。
export MONGODB_URI="<YOUR_CONNECTION_STRING>" ./gradlew bootRun
アプリケーションはポート 8080 で実行されます。前の手順で定義されたエンドポイントに リクエストを送信して、クエリをテストできます。
このアプリケーションのエンドポイントをテストする方法の詳細については、spring-data-unlockedリポジトリの README を参照してください。
追加リソース
spring Data MongoDBの詳細については、spring Data MongoDB のドキュメントを参照してください。
集計パイプラインの詳細については、 MongoDB Serverマニュアルの「 集計 」を参照してください。