Tablestore は、クエリ実行時に指定された条件に基づくサーバー側でのデータフィルタリングをサポートしています。Python SDK でフィルターを使用すると、フィルター条件に一致する行のみが返されます。
前提条件
作業を開始する前に、以下の準備が完了していることを確認してください。
フィルターの仕組み
フィルターは、Tablestore がプライマリキー範囲に一致する行をスキャンした後に、サーバー側で評価されます。フィルターを通過するかどうかに関係なく、スキャンされたすべての行に対して読み取り容量単位 (RCU) が消費されます。不要な RCU 消費を最小限に抑えるため、フィルターを適用する前に正確なプライマリキー範囲を定義してください。
Tablestore では、以下の 2 種類のフィルターが提供されています。
SingleColumnCondition— 単一の属性列の値に基づいて行をフィルタリングします。1 つの列を固定値と比較する必要がある場合に使用します。CompositeColumnCondition— 論理演算子 (AND、OR、NOT) を使用して複数の条件を組み合わせます。複数の列にまたがるフィルター条件や複合式が必要な場合に使用します。最大 32 個の条件をサポートします。
SingleColumnCondition
単一の属性列が比較条件を満たすかどうかに基づいて行をフィルタリングします。
class SingleColumnCondition(ColumnCondition)
コード例
次の例では、プライマリキーが [row1, row3) の範囲にある行に対して範囲クエリを実行し、属性列 col1 の値が val1 と等しい行のみを返します。
try:
# クエリの開始プライマリキーを設定します。
inclusive_start_primary_key = [('id', 'row1')]
# クエリの終了プライマリキーを設定します。終了キーは排他的です。
exclusive_end_primary_key = [('id', 'row3')]
# 条件 col1 == "val1" のフィルターを作成します。
singleColumnCondition = SingleColumnCondition('col1', 'val1', ComparatorType.EQUAL)
# get_range メソッドを呼び出してデータをクエリします。
consumed, next_start_primary_key, row_list, next_token = client.get_range('test_table', Direction.FORWARD,
inclusive_start_primary_key,
exclusive_end_primary_key,
column_filter=singleColumnCondition)
# 結果を処理します。
print('* Read CU Cost: %s' % consumed.read)
print('* Write CU Cost: %s' % consumed.write)
print('* Rows Data:')
for row in row_list:
print(row.primary_key, row.attribute_columns)
except Exception as e:
print("Range get failed with error: %s" % e)
-
指定された属性列が存在しない行を除外するには、以下のように設定します。
singleColumnCondition.pass_if_missing = False -
すべてのデータバージョンを評価し、いずれかのバージョンが条件を満たす場合に行を返すには、以下のように設定します。
singleColumnCondition.latest_version_only = False
CompositeColumnCondition
論理演算子を使用して複数のフィルター条件を組み合わせます。最大 32 個の条件をサポートしており、複雑な式のために CompositeColumnCondition オブジェクトをネストすることも可能です。
class CompositeColumnCondition(ColumnCondition)
コード例
次の例では、プライマリキーが [row1, row3) の範囲にある行に対して範囲クエリを実行し、以下の複合フィルターを適用します。
(col1 == "val1" OR col2 == "val2") AND col3 == "val3"
try:
# クエリの開始プライマリキーを設定します。
inclusive_start_primary_key = [('id', 'row1')]
# クエリの終了プライマリキーを設定します。終了キーは排他的です。
exclusive_end_primary_key = [('id', 'row3')]
# 最初の単一列条件を作成します:col1 == "val1"。
singleColumnCondition1 = SingleColumnCondition('col1', 'val1', ComparatorType.EQUAL)
# 2 番目の単一列条件を作成します:col2 == "val2"。
singleColumnCondition2 = SingleColumnCondition('col2', 'val2', ComparatorType.EQUAL)
# 最初の複合条件を作成します:col1 == "val1" OR col2 == "val2"。
compositeColumnCondition1 = CompositeColumnCondition(LogicalOperator.OR)
compositeColumnCondition1.add_sub_condition(singleColumnCondition1)
compositeColumnCondition1.add_sub_condition(singleColumnCondition2)
# 3 番目の単一列条件を作成します:col3 == "val3"。
singleColumnCondition3 = SingleColumnCondition('col3', 'val3', ComparatorType.EQUAL)
# 最終的な複合条件を作成します:(col1 == "val1" OR col2 == "val2") AND col3 == "val3"。
compositeColumnCondition2 = CompositeColumnCondition(LogicalOperator.AND)
compositeColumnCondition2.add_sub_condition(compositeColumnCondition1)
compositeColumnCondition2.add_sub_condition(singleColumnCondition3)
# get_range メソッドを呼び出してデータをクエリします。
consumed, next_start_primary_key, row_list, next_token = client.get_range('test_table', Direction.FORWARD,
inclusive_start_primary_key,
exclusive_end_primary_key,
column_filter=compositeColumnCondition2)
# 結果を処理します。
print('* Read CU Cost: %s' % consumed.read)
print('* Write CU Cost: %s' % consumed.write)
print('* Rows Data:')
for row in row_list:
print(row.primary_key, row.attribute_columns)
except Exception as e:
print("Range get failed with error: %s" % e)