以下のようなエントリが投稿されていたので、Javaでやったらどうなるか試してみる。Cosmos DBとはいえ、Azure Table互換を使っているので、利用するAPIの実体はTable API。
Integrating Cosmos DB with OData (Part 3)
https://devblogs.microsoft.com/odata/integrating-cosmos-db-with-odata-part-3/
オリジナルのエントリに従い、Table APIを使うCosmos DBを用意する。

[確認と作成]をクリックして内容を確認し、[作成]をクリックしてインスタンスを作成。

データエクスプローラーでTableを作成し、データを追加する。スループットは400のままでよい。

Table APIでは、PartitionKey、RowKey、Timestampは自動生成される。Name、ScoreというフィールドをTableに追加し、値を設定しておく。

値を追加した結果。

この先は接続文字列を取得して、Hello Worldのようなアプリケーションを作る。ここまではオリジナルと同じ。

今回はStorage Table互換APIを使うため、以下の依存関係を追加する。
<!-- Microsoft Azure Storage Client SDK. 執筆時の最新 8.6.0 を使う -->
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-storage</artifactId>
<version>8.6.0</version>
</dependency>
コードを書いていく。エンティティクラスを作成する。これはTableServiceEntityを拡張したもの。
import com.microsoft.azure.storage.table.TableServiceEntity;
public class Student extends TableServiceEntity {
String Name;
Integer Score;
public String getName() {
return Name;
}
public void setName(String name) {
this.Name = name;
}
public Integer getScore() {
return Score;
}
public void setScore(Integer score) {
this.Score = score;
}
}
続いて、CloudTableClientを作成し、参照するTable(今回はstudents)を取得。
final String CONNECTION_STRING="Your Connection String";
CloudTableClient cloudTableClient = CloudStorageAccount.parse(CONNECTION_STRING).createCloudTableClient();
CloudTable table = cloudTableClient.getTableReference("students");
TableQuery<Student> tableQuery = TableQuery.from(Student.class);
TableQuery、つまりselect文を作成する。複数の条件句(where句)はTableQuery#combineFilters() を使って結合する。以下のコードに入っているtake()で、結果セットの先頭から何件取得するかを指定できる。
String filter1 =
TableQuery.generateFilterCondition("Score", QueryComparisons.GREATER_THAN, 150);
String filter2 =
TableQuery.generateFilterCondition("Name", QueryComparisons.EQUAL, "Hassan");
tableQuery = TableQuery.from(Student.class)
.where(TableQuery.combineFilters(filter1, TableQuery.Operators.AND, filter2))
.take(3);
ResultContinuation token = new ResultContinuation();
token.setContinuationType(ResultContinuationType.TABLE);
table.executeSegmented(tableQuery, token)
.getResults()
.forEach(i-> System.out.printf("PartitionKey [%s] Name [%s] Score [%d]\n", i.getPartitionKey(), i.getName(), i.getScore()));
上記コードを実行すると、以下の結果が得られる。
PartitionKey [1] Name [Hassan] Score [155]
ほぼ原文のC#での場合と同じように出来るが、Java APIの場合、OrderByに相当するものがない。そのため、Javaの場合はStream APIなどを使ってFilteringするしかなさそう(あとはStored procedureを使う、ぐらい)。JavaではOrderByを使わないと割り切ったのかはよくわからないが、ちょっとどうかなー、と思う。