Azure Cosmos DB Java SDK v4 を使用するようにアプリケーションを移行する
適用対象: NoSQL
重要
この SDK の詳細については、Azure Cosmos DB Java SDK v4 のリリース ノート、Maven リポジトリ、Azure Cosmos DB Java SDK v4 のパフォーマンスに関するヒント、Azure Cosmos DB Java SDK v4 のトラブルシューティング ガイドを参照してください。
重要
Azure Cosmos DB Java SDK v4 では、スループットが最大 20% 向上し、TCP を利用したダイレクト モードが用意され、最新のバックエンド サービス機能があるので、機会があり次第 v4 にアップグレードすることをお勧めします。 詳しくは、この記事を読み進めてください。
最新の Azure Cosmos DB Java SDK に更新して、Azure Cosmos DB が提供する最善のもの、つまり、競争力のあるパフォーマンス、ファイブ ナイン (99.999%) の可用性、比類のないリソース ガバナンスなどを備えたマネージド非リレーショナル データベースを手に入れます。 この記事では、古い Azure Cosmos DB Java SDK を使用している既存の Java アプリケーションを、NoSQL 用 API 用の新しい Azure Cosmos DB Java SDK 4.0 にアップグレードする方法について説明します。 Azure Cosmos DB Java SDK v4 は、com.azure.cosmos
パッケージに対応しています。 次のいずれかの Azure Cosmos DB Java SDK からアプリケーションを移行する場合、このドキュメントに記載されている手順を使用できます。
- Sync Java SDK 2.x.x
- Async Java SDK 2.x.x
- Java SDK 3.x.x
Azure Cosmos DB Java SDK とパッケージのマッピング
次の表では、さまざまな Azure Cosmos DB Java SDK、パッケージ名、リリース情報を示します。
Java SDK | リリース日 | バンドルされた API | Maven Jar | Java パッケージ名 | API リファレンス | リリース ノート | 廃止日 |
---|---|---|---|---|---|---|---|
Async 2.x.x | 2018 年 6 月 | Async(RxJava) | com.microsoft.azure::azure-cosmosdb |
com.microsoft.azure.cosmosdb.rx |
API | リリース ノート | 2024 年 8 月 31 日 |
Sync 2.x.x | 2018 年 9 月 | 同期 | com.microsoft.azure::azure-documentdb |
com.microsoft.azure.cosmosdb |
API | 2024 年 2 月 29 日 | |
3.x.x | 2019 年 7 月 | Async(Reactor)/Sync | com.microsoft.azure::azure-cosmos |
com.azure.data.cosmos |
API | - | 2024 年 8 月 31 日 |
4.0 | 2020 年 6 月 | Async(Reactor)/Sync | com.azure::azure-cosmos |
com.azure.cosmos |
API | - | - |
SDK レベルの実装の変更
さまざまな SDK 間での主な実装の相違点を次に示します。
RxJava が Azure Cosmos DB Java SDK バージョン 3.x.x および 4.0 ではリアクターに置き換えられている
非同期プログラミングまたはリアクティブ プログラミングに慣れていない場合、非同期プログラミングとプロジェクト リアクターの概要については、「リアクター パターン ガイド」を参照してください。 このガイドは、以前に Azure Cosmos DB Sync Java SDK 2.x.x または Azure Cosmos DB Java SDK 3.x.x Sync API を使用している場合に役立つことがあります。
Azure Cosmos DB Async Java SDK 2.x.x を使用していて、4.0 SDK への移行を計画している場合、リアクターを使用するように RxJava のコードを変換するガイダンスについては、「リアクターと RxJava の比較ガイド」を参照してください。
Azure Cosmos DB Java SDK v4 は、Async API と Sync API の両方に対する直接接続モードを備えている
Azure Cosmos DB Sync Java SDK 2.x.x を使用している場合、Azure Cosmos DB Java SDK 4.0 では、Async API と Sync API の両方について、(HTTP ではなく) TCP に基づく直接接続モードが実装されていることに注意してください。
API レベルの変更
以前の SDK (Java SDK 3.x.x、Async Java SDK 2.x.x、Sync Java SDK 2.x.x) と比較した Azure Cosmos DB Java SDK 4.x.x での API レベルの変更点を次に示します。
Azure Cosmos DB Java SDK 3.x.x と 4.0 では、クライアント リソースが
Cosmos<resourceName>
として参照されています。 たとえば、CosmosClient
、CosmosDatabase
、CosmosContainer
などです。 一方、バージョン 2.x.x の Azure Cosmos DB Java SDK には、一貫した名前付けスキームはありません。Azure Cosmos DB Java SDK 3.x.x と 4.0 では、Sync API と Async API の両方が提供されています。
Java SDK 4.0: クラス名で
Cosmos
の後にAsync
が追加されていない限り、すべてのクラスは Sync API に属します。Java SDK 3.x.x: クラス名で
Cosmos
の後にAsync
が追加されていない限り、すべてのクラスは Async API に属します。Async Java SDK 2.x.x: クラス名は Sync Java SDK 2.x.x に似ていますが、名前は Async で始まります。
階層型の API 構造
次の 4.0 SDK コード スニペットで示すように、Azure Cosmos DB Java SDK 4.0 と 3.x.x では、クライアント、データベース、コンテナーが入れ子として編成された階層型 API 構造が導入されています。
CosmosContainer container = client.getDatabase("MyDatabaseName").getContainer("MyContainerName");
Azure Cosmos DB Java SDK のバージョン 2.x では、リソースとドキュメントに対するすべての操作は、クライアント インスタンスを介して実行されます。
ドキュメントの表現
Azure Cosmos DB Java SDK 4.0 では、カスタム POJO と JsonNodes
が、Azure Cosmos DB のドキュメントを読み書きするための 2 つのオプションです。
Azure Cosmos DB Java SDK 3.x.x では、CosmosItemProperties
オブジェクトがパブリック API によって公開され、ドキュメント表現として提供されます。 このクラスは、バージョン 4.0 では公開されなくなりました。
インポートする
Azure Cosmos DB Java SDK 4.0 のパッケージは、
com.azure.cosmos
で始まりますAzure Cosmos DB Java SDK 3.x.x のパッケージは、
com.azure.data.cosmos
で始まりますAzure Cosmos DB Java SDK 2.x.x Sync API のパッケージは、
com.microsoft.azure.documentdb
で始まりますAzure Cosmos DB Java SDK 4.0 では、入れ子になったパッケージ
com.azure.cosmos.models
に複数のクラスが配置されます。 これらのパッケージには次のものがあります。CosmosContainerResponse
CosmosDatabaseResponse
CosmosItemResponse
- 上記のすべてのパッケージに相当する Async API
CosmosContainerProperties
FeedOptions
PartitionKey
IndexingPolicy
IndexingMode
など
アクセサー
Azure Cosmos DB Java SDK 4.0 では、インスタンス メンバーにアクセスするための get
メソッドと set
メソッドが公開されています。 たとえば、CosmosContainer
インスタンスには、container.getId()
メソッドと container.setId()
メソッドがあります。
これは、fluent インターフェイスを公開する Azure Cosmos DB Java SDK 3.x.x とは異なります。 たとえば、CosmosSyncContainer
インスタンスの container.id()
は、id
の値を取得または設定するためにオーバーロードされます。
依存関係の競合の管理
Azure Cosmos DB Java SDK V2 から V4 にアップグレードすると、SDK で使用されるライブラリが変更されるため、依存関係の競合が発生する可能性があります。 これらの競合を解決するには、依存関係を慎重に管理する必要があります。
新しい依存関係について理解する: Azure Cosmos DB V4 SDK には独自の依存関係セットがあり、これらは以前のバージョンのものとは異なる可能性があります。 次の依存関係について注意してください。
azure-cosmos
reactor-core
reactor-netty
netty-handler
guava
slf4j-api
jackson-databind
jackson-annotations
jackson-core
commons-lang3
commons-collections4
azure-core
azure-core-http-netty
競合する依存関係を削除する: まず、
pom.xml
ファイルから以前のバージョンの SDK に関連する依存関係を削除します。 これには、azure-cosmosdb
と、以前の SDK が持っていた可能性がある推移的依存関係が含まれます。V4 SDK の依存関係を追加する: V4 SDK とその依存関係を
pom.xml
に追加します。 次に例を示します。<dependency> <groupId>com.azure</groupId> <artifactId>azure-cosmos</artifactId> <version>4.x.x</version> <!-- Use the latest version available --> </dependency>
依存関係の競合を確認する: Maven
dependency:tree
コマンドを使用して依存関係ツリーを生成し、競合を特定します。 実行 (Run):mvn dependency:tree
競合するバージョンの依存関係を探します。 これらの競合は、多くの場合、
reactor-core
、netty-handler
、guava
、jackson
などのライブラリで発生します。依存関係管理を使用する: バージョンの競合が発生している場合は、
pom.xml
の<dependencyManagement>
セクションを使用して、問題のあるバージョンをオーバーライドすることが必要になる場合があります。 ここでは、特定のバージョンのreactor-core
を適用する例を示します。<dependencyManagement> <dependencies> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-core</artifactId> <version>3.x.x</version> <!-- Use a compatible version --> </dependency> <!-- Repeat for any other conflicting dependencies --> </dependencies> </dependencyManagement>
推移的依存関係を除外する: 場合によっては、他の依存関係によってもたらされる推移的依存関係を除外することが必要になります。 たとえば、別のライブラリによって競合する古いバージョンの依存関係が取り込まれる場合、次のようにそれを除外できます。
<dependency> <groupId>some.group</groupId> <artifactId>some-artifact</artifactId> <version>x.x.x</version> <exclusions> <exclusion> <groupId>conflicting.group</groupId> <artifactId>conflicting-artifact</artifactId> </exclusion> </exclusions> </dependency>
再構築してテストする: これらの変更を行った後、プロジェクトを再構築して、新しい依存関係が正しく機能し、実行時の競合が発生しないように十分にテストします。
コード スニペットの比較
リソースを作成する
次のコード スニペットは、4.0、3.x.x Async、2.x.x Sync、および 2.x.x Async API 間のリソース作成方法の違いを示しています。
// Create Async client.
// Building an async client is still a sync operation.
CosmosAsyncClient client = new CosmosClientBuilder()
.endpoint("your.hostname")
.key("yourmasterkey")
.consistencyLevel(ConsistencyLevel.EVENTUAL)
.buildAsyncClient();
// Create database with specified name
client.createDatabaseIfNotExists("YourDatabaseName")
.flatMap(databaseResponse -> {
testDatabaseAsync = client.getDatabase("YourDatabaseName");
// Container properties - name and partition key
CosmosContainerProperties containerProperties =
new CosmosContainerProperties("YourContainerName", "/id");
// Provision manual throughput
ThroughputProperties throughputProperties = ThroughputProperties.createManualThroughput(400);
// Create container
return database.createContainerIfNotExists(containerProperties, throughputProperties);
}).flatMap(containerResponse -> {
testContainerAsync = database.getContainer("YourContainerName");
return Mono.empty();
}).subscribe();
項目の操作
次のコード スニペットは、4.0、3.x.x Async、2.x.x Sync、および 2.x.x Async API 間の項目操作の実行方法の違いを示しています。
// Container is created. Generate many docs to insert.
int number_of_docs = 50000;
ArrayList<JsonNode> docs = generateManyDocs(number_of_docs);
// Insert many docs into container...
Flux.fromIterable(docs)
.flatMap(doc -> testContainerAsync.createItem(doc))
.subscribe(); // ...Subscribing triggers stream execution.
インデックス作成
次のコード スニペットは、4.0、3.x.x Async、2.x.x Sync、および 2.x.x Async API 間のインデックス作成方法の違いを示しています。
CosmosContainerProperties containerProperties = new CosmosContainerProperties(containerName, "/lastName");
// Custom indexing policy
IndexingPolicy indexingPolicy = new IndexingPolicy();
indexingPolicy.setIndexingMode(IndexingMode.CONSISTENT);
// Included paths
List<IncludedPath> includedPaths = new ArrayList<>();
includedPaths.add(new IncludedPath("/*"));
indexingPolicy.setIncludedPaths(includedPaths);
// Excluded paths
List<ExcludedPath> excludedPaths = new ArrayList<>();
excludedPaths.add(new ExcludedPath("/name/*"));
indexingPolicy.setExcludedPaths(excludedPaths);
containerProperties.setIndexingPolicy(indexingPolicy);
ThroughputProperties throughputProperties = ThroughputProperties.createManualThroughput(400);
database.createContainerIfNotExists(containerProperties, throughputProperties);
CosmosAsyncContainer containerIfNotExists = database.getContainer(containerName);
ストアド プロシージャ
次のコード スニペットは、4.0、3.x.x Async、2.x.x Sync、および 2.x.x Async API 間のストアド プロシージャの作成方法の違いを示しています。
logger.info("Creating stored procedure...\n");
String sprocId = "createMyDocument";
String sprocBody = "function createMyDocument() {\n" +
"var documentToCreate = {\"id\":\"test_doc\"}\n" +
"var context = getContext();\n" +
"var collection = context.getCollection();\n" +
"var accepted = collection.createDocument(collection.getSelfLink(), documentToCreate,\n" +
" function (err, documentCreated) {\n" +
"if (err) throw new Error('Error' + err.message);\n" +
"context.getResponse().setBody(documentCreated.id)\n" +
"});\n" +
"if (!accepted) return;\n" +
"}";
CosmosStoredProcedureProperties storedProcedureDef = new CosmosStoredProcedureProperties(sprocId, sprocBody);
container.getScripts()
.createStoredProcedure(storedProcedureDef,
new CosmosStoredProcedureRequestOptions()).block();
// ...
logger.info(String.format("Executing stored procedure %s...\n\n", sprocId));
CosmosStoredProcedureRequestOptions options = new CosmosStoredProcedureRequestOptions();
options.setPartitionKey(new PartitionKey("test_doc"));
container.getScripts()
.getStoredProcedure(sprocId)
.execute(null, options)
.flatMap(executeResponse -> {
logger.info(String.format("Stored procedure %s returned %s (HTTP %d), at cost %.3f RU.\n",
sprocId,
executeResponse.getResponseAsString(),
executeResponse.getStatusCode(),
executeResponse.getRequestCharge()));
return Mono.empty();
}).block();
Change Feed
次のコード スニペットでは、4.0 と 3.x.x の Async API での変更フィード操作の実行方法の違いを示します。
ChangeFeedProcessor changeFeedProcessorInstance =
new ChangeFeedProcessorBuilder()
.hostName(hostName)
.feedContainer(feedContainer)
.leaseContainer(leaseContainer)
.handleChanges((List<JsonNode> docs) -> {
logger.info("--->setHandleChanges() START");
for (JsonNode document : docs) {
try {
//Change Feed hands the document to you in the form of a JsonNode
//As a developer you have two options for handling the JsonNode document provided to you by Change Feed
//One option is to operate on the document in the form of a JsonNode, as shown below. This is great
//especially if you do not have a single uniform data model for all documents.
logger.info("---->DOCUMENT RECEIVED: " + OBJECT_MAPPER.writerWithDefaultPrettyPrinter()
.writeValueAsString(document));
//You can also transform the JsonNode to a POJO having the same structure as the JsonNode,
//as shown below. Then you can operate on the POJO.
CustomPOJO pojo_doc = OBJECT_MAPPER.treeToValue(document, CustomPOJO.class);
logger.info("----=>id: " + pojo_doc.getId());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
logger.info("--->handleChanges() END");
})
.buildChangeFeedProcessor();
// ...
changeFeedProcessorInstance.start()
.subscribeOn(Schedulers.elastic())
.subscribe();
コンテナー レベルの Time-To-Live (TTL)
次のコード スニペットは、4.0、3.x.x Async、2.x.x Sync、および 2.x.x Async API 間の、コンテナー内のデータに対する Time-To-Live の作成方法の違いを示しています。
CosmosAsyncContainer container;
// Create a new container with TTL enabled with default expiration value
CosmosContainerProperties containerProperties = new CosmosContainerProperties("myContainer", "/myPartitionKey");
containerProperties.setDefaultTimeToLiveInSeconds(90 * 60 * 60 * 24);
ThroughputProperties throughputProperties = ThroughputProperties.createManualThroughput(400);
database.createContainerIfNotExists(containerProperties, throughputProperties).block();
container = database.getContainer("myContainer");
項目レベルの Time-To-Live (TTL)
次のコード スニペットは、4.0、3.x.x Async、2.x.x Sync、および 2.x.x Async API 間の項目に対する Time-To-Live の作成方法の違いを示しています。
// Include a property that serializes to "ttl" in JSON
class SalesOrder
{
private String id;
private String customerId;
private Integer ttl;
public SalesOrder(String id, String customerId, Integer ttl) {
this.id = id;
this.customerId = customerId;
this.ttl = ttl;
}
public String getId() {return this.id;}
public void setId(String new_id) {this.id = new_id;}
public String getCustomerId() {return this.customerId;}
public void setCustomerId(String new_cid) {this.customerId = new_cid;}
public Integer getTtl() {return this.ttl;}
public void setTtl(Integer new_ttl) {this.ttl = new_ttl;}
//...
}
// Set the value to the expiration in seconds
SalesOrder salesOrder = new SalesOrder(
"SO05",
"CO18009186470",
60 * 60 * 24 * 30 // Expire sales orders in 30 days
);
次のステップ
- V4 SDK を使用して Azure Cosmos DB for NoSQL データを管理するための Java アプリを作成する
- リアクター ベースの Java SDK について学習する
- 「リアクターと RxJava の比較ガイド」で、RxJava の非同期コードをリアクターの非同期コードに変換する方法について学習する
- Azure Cosmos DB に移行する容量計画を実行しようとしていますか?
- 既存のデータベース クラスター内の仮想コアとサーバーの数のみがわかっている場合は、仮想コア数または仮想 CPU 数を使用した要求ユニットの見積もりに関するページを参照してください
- 現在のデータベース ワークロードに対する通常の要求レートがわかっている場合は、Azure Cosmos DB Capacity Planner を使用した要求ユニットの見積もりに関するページを参照してください