フィルターを設定すると、Tablestoreはサーバー上でクエリ結果をフィルタリングします。フィルター条件に一致する行のみが返されます。そのため、この機能は転送されるデータ量を削減し、応答時間を短縮します。
シナリオ
結果を直接フィルタリングする
たとえば、モノのインターネット(IoT)ベースのスマート電力量計は、電圧、電流、使用量などの情報を15秒ごとにTablestoreテーブルに書き込みます。ケーブルを検査する必要があるかどうかを判断するために、異常な電圧データとその他の関連データを日次分析用にクエリする必要があります。
GetRange操作を呼び出して、電力量計によって1日に生成された監視データを読み取り、データをフィルタリング(5,760レコード)して、電圧が不安定なときに収集された10レコードを取得できます。
フィルターを使用すると、分析する必要がある10レコードのみが返されます。フィルターは、返されるデータ量を削減し、予備的なデータ処理の必要性を排除します。これにより、開発コストが削減されます。
正規表現マッチングとデータ変換後に結果をフィルタリングする
データが列にJSON文字列などのカスタム形式で保存されており、サブフィールド値をクエリする場合は、正規表現を使用して一致させ、値を必要なデータ型に変換できます。その後、フィルターを使用して必要なデータを取得できます。
たとえば、列に格納されているデータは
{cluster_name:name1,lastupdatetime:12345}
形式です。行lastupdatetime>12345
の値をフィルタリングしてクエリする必要がある場合は、正規表現lastupdatetime:([0-9]+)}
を使用して列のサブフィールドのデータと一致させ、一致した結果を数値型に変換してから、数値データを一致した結果と比較します。このようにして、必要なデータ行を取得できます。
概要
GetRow、BatchGetRow、またはGetRange操作を呼び出してデータをクエリする場合、フィルターを使用してフィルター条件に一致する行のみを返すことができます。これらの場合、これらの操作のネイティブセマンティクスと制限は変更されません。詳細については、データの読み取りを参照してください。
フィルターを使用する場合、ビジネス要件に基づいて次の設定を構成できます。
参照列が行に存在しない場合は、PassIfMissingパラメーターを設定して、行を返すかどうかを決定します。
参照列に複数のバージョンのデータが含まれている場合は、比較に最新バージョンのデータのみを使用するかどうかを指定します。
正規表現を使用してサブフィールド値を照合します。
関係演算子と論理演算子を使用してフィルター条件を作成します。
使用可能なフィルターは、1つ以上の参照列の列値に基づいて行をフィルタリングするSingleColumnValueFilter、SingleColumnValueRegexFilter、およびCompositeColumnValueFilterです。
フィルター | 説明 |
参照列の値に基づいて行をフィルタリングするかどうかを決定します。 | |
正規表現を使用してString型の列値を照合し、一致した部分文字列を抽出します。次に、抽出された部分文字列のデータ型をString、Integer、またはDoubleに変換し、変換後の値をフィルタリングします。 正規表現は次の条件を満たす必要があります。
| |
複数の参照列の値の一致結果の論理結合に基づいて行をフィルタリングするかどうかを決定します。 |
使用上の注意
フィルター条件は、=、!=、>、> =、<、および<=の関係演算子と、NOT、AND、およびORの論理演算子をサポートします。フィルター条件には、最大10個のサブ条件を含めることができます。
フィルターで使用される参照列は、クエリ結果に含まれている必要があります。データの読み取り元として指定された列に参照列が含まれていない場合、フィルターは参照列の値をクエリできません。
GetRange操作を使用する場合、一度に最大5,000行または4 MBのデータをスキャンできます。
スキャンの範囲内でフィルター条件に一致するデータがない場合、返される行は空です。ただし、NextStartPrimaryKeyは空でない場合があります。NextStartPrimaryKeyが空でない場合は、パラメーター値を使用して、NextStartPrimaryKeyの戻り値が空になるまでスキャンを続けます。
メソッド
Tablestore SDKを使用してのみフィルターを使用できます。
Java用Tablestore SDK、Go用Tablestore SDK、Python用Tablestore SDK、Node.js用Tablestore SDK、.NET用Tablestore SDK、およびPHP用Tablestore SDKを使用してフィルターを使用できます。この例では、Java用Tablestore SDKを使用します。
SingleColumnValueFilterを使用してデータをフィルタリングする
次のサンプルコードは、データテーブルの行から最新バージョンのデータを読み取り、フィルターを使用してCol0列の値に基づいてデータをフィルタリングする方法の例を示しています。
private static void getRow(SyncClient client, String pkValue) {
// プライマリキーを構築します。
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue));
PrimaryKey primaryKey = primaryKeyBuilder.build();
// テーブル名とプライマリキーを指定して、データの行を読み取ります。
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<TABLE_NAME>", primaryKey);
// MaxVersionsパラメーターを1に設定して、最新バージョンのデータを読み取ります。
criteria.setMaxVersions(1);
// Col0列の値が0である行を返すようにフィルターを設定します。
SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("Col0",
SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromLong(0));
// Col0列が存在しない場合、行は返されません。
singleColumnValueFilter.setPassIfMissing(false);
criteria.setFilter(singleColumnValueFilter);
GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
Row row = getRowResponse.getRow();
System.out.println("読み取り完了。結果:");
System.out.println(row);
}
SingleColumnValueRegexFilterを使用して正規表現マッチングに基づいてデータをフィルタリングする
次のサンプルコードは、プライマリキー値がCol1列の["pk:2020-01-01.log", "pk:2021-01-01.log")
の範囲内にあるデータを読み取り、正規表現を使用してCol1列のデータをフィルタリングする方法の例を示しています。
private static void getRange(SyncClient client) {
// データテーブルの名前を指定します。
RangeRowQueryCriteria criteria = new RangeRowQueryCriteria("<TABLE_NAME>");
// 読み取るデータのプライマリキーの範囲として["pk:2020-01-01.log", "pk:2021-01-01.log"]を指定します。範囲は左閉右開区間です。
PrimaryKey pk0 = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("2020-01-01.log"))
.build();
PrimaryKey pk1 = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("2021-01-01.log"))
.build();
criteria.setInclusiveStartPrimaryKey(pk0);
criteria.setExclusiveEndPrimaryKey(pk1);
// MaxVersionsパラメーターを1に設定して、最新バージョンのデータを読み取ります。
criteria.setMaxVersions(1);
// フィルターを設定します。cast<int>(regex(Col1))が100より大きい場合、行が返されます。
RegexRule regexRule = new RegexRule("t1:([0-9]+),", RegexRule.CastType.VT_INTEGER);
SingleColumnValueRegexFilter filter = new SingleColumnValueRegexFilter("Col1",
regexRule,SingleColumnValueRegexFilter.CompareOperator.GREATER_THAN,ColumnValue.fromLong(100));
criteria.setFilter(filter);
while (true) {
GetRangeResponse resp = client.getRange(new GetRangeRequest(criteria));
for (Row row : resp.getRows()) {
// 何かをする
System.out.println(row);
}
if (resp.getNextStartPrimaryKey() != null) {
criteria.setInclusiveStartPrimaryKey(resp.getNextStartPrimaryKey());
} else {
break;
}
}
}
CompositeColumnValueFilterを使用してデータをフィルタリングする
次のサンプルコードは、プライマリキーが["a","h")
の範囲内にある行を返すために使用されます。さらに、Col0の値は0であり、Col1の値は100より大きい、またはCol2の値は10以下です。
private static void getRange(SyncClient client) {
// データテーブルの名前を指定します。
RangeRowQueryCriteria criteria = new RangeRowQueryCriteria("<TABLE_NAME>");
// プライマリキーの範囲を指定します。プライマリキーの範囲は左閉右開区間です。
PrimaryKey pk0 = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("a"))
.build();
PrimaryKey pk1 = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("h"))
.build();
criteria.setInclusiveStartPrimaryKey(pk0);
criteria.setExclusiveEndPrimaryKey(pk1);
// maxVersionsパラメーターを1に設定して、最新バージョンのデータを読み取ります。
criteria.setMaxVersions(1);
// composite1条件を(Col0 == 0) AND (Col1 > 100)に設定します。
CompositeColumnValueFilter composite1 = new CompositeColumnValueFilter(CompositeColumnValueFilter.LogicOperator.AND);
SingleColumnValueFilter single1 = new SingleColumnValueFilter("Col0",
SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromLong(0));
SingleColumnValueFilter single2 = new SingleColumnValueFilter("Col1",
SingleColumnValueFilter.CompareOperator.GREATER_THAN, ColumnValue.fromLong(100));
composite1.addFilter(single1);
composite1.addFilter(single2);
// composite2条件を( (Col0 == 0) AND (Col1 > 100) ) OR (Col2 <= 10)に設定します。
CompositeColumnValueFilter composite2 = new CompositeColumnValueFilter(CompositeColumnValueFilter.LogicOperator.OR);
SingleColumnValueFilter single3 = new SingleColumnValueFilter("Col2",
SingleColumnValueFilter.CompareOperator.LESS_EQUAL, ColumnValue.fromLong(10));
composite2.addFilter(composite1);
composite2.addFilter(single3);
criteria.setFilter(composite2);
while (true) {
GetRangeResponse resp = client.getRange(new GetRangeRequest(criteria));
for (Row row : resp.getRows()) {
// 何かをする
System.out.println(row);
}
if (resp.getNextStartPrimaryKey() != null) {
criteria.setInclusiveStartPrimaryKey(resp.getNextStartPrimaryKey());
} else {
break;
}
}
}
課金
フィルターの実装は、既存の課金ルールには影響しません。
フィルターは返されるデータ量を削減しますが、フィルタリングはデータが返される前にサーバー上で実行されるため、ディスクI/Oの使用量は変わりません。そのため、フィルターを使用するかどうかに関係なく、同じ数の読み取りCUが消費されます。たとえば、GetRange操作を呼び出して100レコード(200 KB)のデータを読み取り、これらのレコードをフィルタリングして10レコード(20 KB)を取得する場合、50の読み取りCUが消費されます。
FAQ
参考資料
アプリケーションが異なる属性をクエリ条件として使用してデータをクエリする必要がある場合は、これらの属性をセカンダリインデックステーブルのプライマリキー列として指定して、クエリを高速化できます。詳細については、セカンダリインデックスを参照してください。
ビジネスに多次元クエリとデータ分析が必要な場合は、検索インデックスを作成し、必要な属性を検索インデックスのフィールドとして指定できます。その後、検索インデックスを使用してデータをクエリおよび分析できます。多次元クエリには、非プライマリキー列に基づくクエリ、ブールクエリ、およびあいまいクエリが含まれます。データ分析要件には、極値の取得、行数のカウント、データのグループ化が含まれます。詳細については、検索インデックスを参照してください。