フルテーブルスキャンや範囲読み取りでは、アプリケーション側で後から破棄される多数の行が返されるため、帯域幅が無駄になります。フィルターはサーバー上でプロパティ列の値を評価し、条件に一致する行のみを返すことで、ネットワークトラフィックを削減します。Tablestore SDK for Java は、単一列の比較、正規表現で抽出した部分文字列の比較、および複数条件の論理的な組み合わせをサポートしています。
前提条件
Tablestore SDK for Java をインストールし、クライアントを初期化します。
フィルターの仕組み
フィルターは、各行の読み取り後にサーバー上で実行され、条件に一致する行のみを返します。フィルタリングは読み取り後に実行されるため、スキャンされる行数は削減されませんが、ネットワーク経由で送信されるデータ量は削減されます。
setFilter メソッドを呼び出して、クエリリクエストにフィルターをアタッチします。サポートされているリクエストクラスは、SingleRowQueryCriteria、RangeRowQueryCriteria、MultiRowQueryCriteria、および RangeIteratorParameter です。Tablestore SDK for Java は 3 種類のフィルターを提供します。
-
SingleColumnValueFilter: 1 つのプロパティ列の値を、関係演算子を使用してターゲット値と比較します。
-
SingleColumnValueRegexFilter: 正規表現で
Stringプロパティ列から部分文字列を抽出し、ターゲット型に変換してターゲット値と比較します。 -
CompositeColumnValueFilter は、論理演算子 (
AND、OR、またはNOT) を使用して複数のフィルターを組み合わせるものです。複合フィルターは、最大 32 個のサブ条件に対応しています。
これら 3 つのフィルターのクラスシグネチャは、以下のとおりです。
public class SingleColumnValueFilter extends ColumnValueFilter
public class SingleColumnValueRegexFilter extends ColumnValueFilter
public class CompositeColumnValueFilter extends ColumnValueFilter
次の例では、3 つの中で最も一般的な SingleColumnValueFilter を使用して、filter_demo テーブルから col1 列が val1 に等しい行を読み取ります。
RangeRowQueryCriteria criteria = new RangeRowQueryCriteria("filter_demo");
PrimaryKeyBuilder startBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
criteria.setInclusiveStartPrimaryKey(startBuilder.build());
PrimaryKeyBuilder endBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setExclusiveEndPrimaryKey(endBuilder.build());
criteria.setMaxVersions(1);
// フィルターを構築: col1 == "val1"
SingleColumnValueFilter filter = new SingleColumnValueFilter(
"col1",
SingleColumnValueFilter.CompareOperator.EQUAL,
ColumnValue.fromString("val1"));
criteria.setFilter(filter);
GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
System.out.println("Matched rows: " + response.getRows().size());
パラメーター
SingleColumnValueFilter
シグネチャ: new SingleColumnValueFilter(columnName, operator, columnValue)。
|
名前 |
型 |
説明 |
|
columnName (必須) |
String |
評価するプロパティ列の名前。 |
|
operator (必須) |
CompareOperator |
関係演算子。有効な値:
|
|
columnValue (必須) |
ColumnValue |
比較に使用する値。 |
|
passIfMissing (オプション) |
boolean |
対象の列を含まない行を返すかどうか。デフォルトは 対象列を含まない行を除外するには、 |
|
latestVersionsOnly (オプション) |
boolean |
カラムの最新バージョンのみを評価するかどうか。 デフォルトは
|
SingleColumnValueRegexFilter
シグネチャ: new SingleColumnValueRegexFilter(columnName, regexRule, operator, columnValue)。String 型のプロパティ列のみが正規表現フィルタリングをサポートします。
|
名前 |
型 |
説明 |
|
columnName (必須) |
String |
評価するプロパティ列の名前です。この列は |
|
regexRule (必須) |
RegexRule |
regex マッチングルール。これには、
|
|
operator (必須) |
CompareOperator |
関係演算子。有効な値は |
|
columnValue (必須) |
ColumnValue |
比較に使用する値。型は |
CompositeColumnValueFilter
シグネチャ: new CompositeColumnValueFilter(logicOperator)。サブフィルターは addFilter() を呼び出して追加します。複合フィルターは最大 32 個のサブ条件をサポートします。
|
名前 |
型 |
説明 |
|
logicOperator (必須) |
LogicOperator |
論理演算子。有効な値:
|
|
filters (必須) |
List<ColumnValueFilter> |
論理演算子によって結合されたサブフィルターです。各サブフィルターは |
例
正規表現で抽出した部分文字列の比較
RegexRule を使用して、列の値から部分文字列を抽出し、その部分文字列をターゲット値と比較します。 次の例では、正規表現 1([a-z]+)5 を col2 に適用し、最初のグループをキャプチャして、文字列 aaa と比較します。
RangeRowQueryCriteria criteria = new RangeRowQueryCriteria("filter_demo");
PrimaryKeyBuilder startBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
criteria.setInclusiveStartPrimaryKey(startBuilder.build());
PrimaryKeyBuilder endBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setExclusiveEndPrimaryKey(endBuilder.build());
criteria.setMaxVersions(1);
// 正規表現 "1([a-z]+)5" は最初のグループをキャプチャします。castType=VT_STRING は結果を文字列として比較します。
RegexRule regexRule = new RegexRule("1([a-z]+)5", RegexRule.CastType.VT_STRING);
SingleColumnValueRegexFilter filter = new SingleColumnValueRegexFilter(
"col2",
regexRule,
SingleColumnValueRegexFilter.CompareOperator.EQUAL,
ColumnValue.fromString("aaa"));
criteria.setFilter(filter);
GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
System.out.println("Matched rows: " + response.getRows().size());
論理演算子を使用した複数のフィルターの結合
CompositeColumnValueFilter を使用して、複数のフィルターを論理演算子で組み合わせます。 複合フィルターはネストできます。 次の例では、条件 (col1 == "val1" OR cast<String>(reg(col2)) >= "aaa") AND col3 == "val3" を構築します。
RangeRowQueryCriteria criteria = new RangeRowQueryCriteria("filter_demo");
PrimaryKeyBuilder startBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
criteria.setInclusiveStartPrimaryKey(startBuilder.build());
PrimaryKeyBuilder endBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setExclusiveEndPrimaryKey(endBuilder.build());
criteria.setMaxVersions(1);
// リーフ 1: col1 == "val1"
SingleColumnValueFilter leaf1 = new SingleColumnValueFilter(
"col1",
SingleColumnValueFilter.CompareOperator.EQUAL,
ColumnValue.fromString("val1"));
// リーフ 2: cast<String>(reg(col2)) >= "aaa"
RegexRule regexRule = new RegexRule("1([a-z]+)5", RegexRule.CastType.VT_STRING);
SingleColumnValueRegexFilter leaf2 = new SingleColumnValueRegexFilter(
"col2",
regexRule,
SingleColumnValueRegexFilter.CompareOperator.GREATER_EQUAL,
ColumnValue.fromString("aaa"));
// OR 結合: leaf1 OR leaf2
CompositeColumnValueFilter orFilter = new CompositeColumnValueFilter(
CompositeColumnValueFilter.LogicOperator.OR);
orFilter.addFilter(leaf1);
orFilter.addFilter(leaf2);
// リーフ 3: col3 == "val3"
SingleColumnValueFilter leaf3 = new SingleColumnValueFilter(
"col3",
SingleColumnValueFilter.CompareOperator.EQUAL,
ColumnValue.fromString("val3"));
// AND 結合: (leaf1 OR leaf2) AND leaf3
CompositeColumnValueFilter andFilter = new CompositeColumnValueFilter(
CompositeColumnValueFilter.LogicOperator.AND);
andFilter.addFilter(orFilter);
andFilter.addFilter(leaf3);
criteria.setFilter(andFilter);
GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
System.out.println("Matched rows: " + response.getRows().size());
欠落している列と履歴バージョンの評価の制御
setPassIfMissing で対象列を含まない行を返すかどうかを制御し、setLatestVersionsOnly で履歴バージョンも評価対象とするかどうかを制御します。
SingleColumnValueFilter filter = new SingleColumnValueFilter(
"col1",
SingleColumnValueFilter.CompareOperator.EQUAL,
ColumnValue.fromString("val1"));
// col1 を含まない行をスキップします (デフォルトでは返されます)。
filter.setPassIfMissing(false);
// 全バージョンを評価し、いずれかが一致すれば行を返します (デフォルトでは、最新バージョンのみが評価されます)。
filter.setLatestVersionsOnly(false);
criteria.setFilter(filter);