Tablestore SDK for Java は、プライマリキー範囲内の複数行を読み取るためのイテレーターを提供します。このイテレーターは、ページ分割されたリクエストを自動的に発行するため、一度に 1 行ずつ処理する広範囲のスキャンに役立ちます。
前提条件
Tablestore SDK for Java をインストールし、クライアントを初期化します。
説明
public Iterator<Row> createRangeIterator(RangeIteratorParameter rangeIteratorParameter) throws TableStoreException, ClientException
プライマリキー範囲に対するイテレーターを作成し、標準の Java Iterator<Row> を返します。iterator.next() を呼び出すたびに、内部バッファーから行が返され、バッファーが空になると次のバッチリクエストが発行されます。手動で nextStartPrimaryKey を追跡したり、getRange をループ処理したりする必要はありません。
次の例では、range_iter_demo テーブルをプライマリキー row1 から開始し、テーブルの末尾まで正順で反復処理して、各行を出力します。
String tableName = "range_iter_demo";
RangeIteratorParameter parameter = new RangeIteratorParameter(tableName);
// 開始プライマリキー (このキーを含む)
PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
parameter.setInclusiveStartPrimaryKey(startPkBuilder.build());
// 終了プライマリキー (このキーを含まない)。INF_MAX はテーブルの末尾まで読み取ります。
PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
parameter.setExclusiveEndPrimaryKey(endPkBuilder.build());
parameter.setMaxVersions(1);
Iterator<Row> iterator = client.createRangeIterator(parameter);
int count = 0;
while (iterator.hasNext()) {
Row row = iterator.next();
System.out.println(row);
count++;
}
System.out.println("Total rows iterated: " + count);
パラメーター
RangeIteratorParameter を使用して、反復クエリ条件を渡します。パラメーターは以下のとおりです:
|
名前 |
型 |
説明 |
|
tableName (必須) |
String |
読み取るテーブルの名前。 |
|
inclusiveStartPrimaryKey (必須) |
PrimaryKey |
開始プライマリキー。プライマリキー列の名前と値を含みます。
|
|
exclusiveEndPrimaryKey (必須) |
PrimaryKey |
終了プライマリキー。プライマリキー列の名前と値を含みます。
|
|
direction (任意) |
Direction |
読み取り方向。
|
|
maxVersions (maxVersions または timeRange のいずれか必須) |
OptionalValue<Integer> |
属性列ごとに返されるバージョンの最大数。 一致するバージョンがこの最大数を超えた場合、Tablestore は新しいバージョンから古い順に、最大数に達するまでバージョンを返します。 |
|
timeRange (maxVersions または timeRange のいずれか必須) |
OptionalValue<TimeRange> |
バージョンの範囲。 各属性列は複数のバージョンを持つことができます。バージョン範囲を設定すると、その範囲内のデータのみが返されます。 |
|
maxCount (任意) |
int |
イテレーターが返す行の最大合計数。0 より大きい値を指定する必要があります。 |
|
bufferSize (任意) |
int |
内部リクエストごとにフェッチされる行数。0 より大きい値を指定する必要があります。 大規模なスキャン中にピーク時のメモリ使用量を削減するには、この値を小さく設定します。現在のバッチがなくなると、イテレーターは中断したところから次のバッチを自動的にリクエストします。 |
|
columnsToGet (任意) |
Set<String> |
読み取る列。プライマリキー列または属性列を指定できます。
|
|
filter (任意) |
OptionalValue<Filter> |
フィルター条件。詳細については、「フィルターの使用」をご参照ください。
|
例
逆順の反復処理
setDirection(Direction.BACKWARD) を使用すると、逆順で反復処理できます。逆順の反復処理の場合、開始プライマリキーは終了プライマリキーより大きい必要があります。
String tableName = "range_iter_demo";
RangeIteratorParameter parameter = new RangeIteratorParameter(tableName);
parameter.setDirection(Direction.BACKWARD);
// 逆順の反復処理の場合、開始プライマリキーは終了プライマリキーより大きくする必要があります。
PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
parameter.setInclusiveStartPrimaryKey(startPkBuilder.build());
PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
parameter.setExclusiveEndPrimaryKey(endPkBuilder.build());
parameter.setMaxVersions(1);
Iterator<Row> iterator = client.createRangeIterator(parameter);
while (iterator.hasNext()) {
Row row = iterator.next();
System.out.println(row);
}
行の合計数の制限
setMaxCount を使用すると、イテレーターが返す行の合計数を制限できます。これは、上位 N 件の読み取りに役立ち、不要なスキャンを回避できます。
String tableName = "range_iter_demo";
RangeIteratorParameter parameter = new RangeIteratorParameter(tableName);
PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MIN);
parameter.setInclusiveStartPrimaryKey(startPkBuilder.build());
PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
parameter.setExclusiveEndPrimaryKey(endPkBuilder.build());
parameter.setMaxVersions(1);
// 最大 3 行を返します。
parameter.setMaxCount(3);
Iterator<Row> iterator = client.createRangeIterator(parameter);
while (iterator.hasNext()) {
Row row = iterator.next();
System.out.println(row);
}
バッチサイズによるメモリの最適化
setBufferSize を使用すると、内部リクエストごとにフェッチされる行数を制御できます。大規模なスキャン中にピーク時のメモリ使用量を削減するには、この値を小さく設定します。
String tableName = "range_iter_demo";
RangeIteratorParameter parameter = new RangeIteratorParameter(tableName);
PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MIN);
parameter.setInclusiveStartPrimaryKey(startPkBuilder.build());
PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
parameter.setExclusiveEndPrimaryKey(endPkBuilder.build());
parameter.setMaxVersions(1);
// 内部リクエストごとに 2 行をフェッチします。
parameter.setBufferSize(2);
Iterator<Row> iterator = client.createRangeIterator(parameter);
while (iterator.hasNext()) {
Row row = iterator.next();
System.out.println(row);
}