ポストクエリフィルター (フィルター) は、Tablestore の多次元インデックスの機能で、クエリ結果に追加のフィルターを適用します。これにより、内部のクエリ オプティマイザーを手動で制御し、特定のクエリ条件を最終段階で強制的に実行させることができます。この機能を正しく使用することで、クエリのパフォーマンスを大幅に向上させることができます。
ポストクエリフィルター機能は、Java SDK バージョン 5.17.5 以降でサポートされています。この機能を使用するには、Tablestore のテクニカルサポートに連絡して有効化を依頼する必要があります。
機能アーキテクチャ
ポストクエリフィルターは、多層クエリ アーキテクチャに基づいています:
SearchRequest:クエリリクエストの最上位コンテナーです。テーブル名、インデックス名、および特定のクエリ構成が含まれます。
SearchQuery:コアとなるクエリ構成です。メインのクエリ条件 (`Query`) と、オプションのクエリフィルター (`SearchFilter`) が含まれます。
Query:メインのクエリ条件です。多次元インデックスのすべてのクエリタイプとデータ型をサポートし、初期のデータ検索に使用されます。
SearchFilter:セカンダリフィルターです。メインのクエリ結果に対して詳細なフィルタリングを行うためのフィルター条件が含まれます。
制限事項
ポストクエリフィルターは、多次元インデックスクエリと併用する必要があります。サポートされているクエリタイプは、`TermQuery`、`TermsQuery`、`RangeQuery`、`ExistsQuery`、および `BoolQuery` です。
`BoolQuery` の場合、`mustQueries`、`mustNotQueries`、および `shouldQueries` 句はサポートされていますが、`filterQueries` 句はサポートされていません。
フィルタリングは、`enableSortAndAgg` プロパティが有効になっている `Keyword`、`Long`、および `Double` 型のフィールドでのみサポートされます。
ポストクエリフィルターは重みの設定をサポートしていません。
前提条件
メソッドの説明
public SearchResponse search(SearchRequest searchRequest) throws TableStoreException, ClientExceptionサンプルコード
以下の例は、ポストクエリフィルター機能の使用方法を示しています。メインのクエリ条件は、まず `col_keyword` フィールドが `value` であるデータを照合します。次に、フィルター条件で `col_long` フィールドの値が 1 から 10 の範囲にあるレコードを選択します。
命令型 API 呼び出し
private static void queryUsingSetter(SyncClient client) { // [必須] ご利用のテーブル名に置き換えてください。 String tableName = "<TABLE_NAME>"; // [必須] ご利用の多次元インデックス名に置き換えてください。 String indexName = "<SEARCH_INDEX_NAME>"; // メインクエリの構築:terms クエリを使用した複数値完全一致検索。 TermsQuery termsQuery = new TermsQuery(); termsQuery.setFieldName("col_keyword"); termsQuery.addTerm(ColumnValue.fromString("value")); // フィルター条件の構築:col_long フィールドの値が (1, 10) の範囲内にある。 RangeQuery rangeQuery = new RangeQuery(); rangeQuery.setFieldName("col_long"); rangeQuery.setFrom(ColumnValue.fromLong(1)); rangeQuery.setTo(ColumnValue.fromLong(10)); // SearchFilter の組み立て。 SearchFilter searchFilter = new SearchFilter(); searchFilter.setQuery(rangeQuery); // 完全な SearchQuery への結合。 SearchQuery searchQuery = new SearchQuery(); searchQuery.setQuery(termsQuery); searchQuery.setFilter(searchFilter); // リクエストの構築。 SearchRequest searchRequest = new SearchRequest(tableName, indexName, searchQuery); // デフォルトでは、プライマリキー列のみが返されます。必要に応じて返す列を設定します。 SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet(); // 多次元インデックスからすべての列を返すように設定します。 columnsToGet.setReturnAllFromIndex(true); searchRequest.setColumnsToGet(columnsToGet); try { SearchResponse resp = client.search(searchRequest); System.out.println("行: " + resp.getRows()); } catch (Exception e) { System.err.println("検索に失敗しました: " + e.getMessage()); } }特定の列またはすべての列を返すようにクエリを構成できます。
SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet(); // 特定の列を返します。 columnsToGet.setColumns(Arrays.asList("col_long", "col_keyword")); // 列を指定します。 // または、すべての列を返します。 // columnsToGet.setReturnAll(true); searchRequest.setColumnsToGet(columnsToGet);一致した行の総数をカウントするには、`totalCount` 機能を有効にして、応答からカウントを取得します。
// searchQuery で totalCount 統計を有効にします。 searchQuery.setTrackTotalCount(SearchQuery.TRACK_TOTAL_COUNT); // 結果から行の総数を出力します。 System.out.println("合計カウント (一致): " + resp.getTotalCount());
Builder パターン API 呼び出し
private static void queryUsingBuilder(SyncClient client) { // [必須] ご利用のテーブル名に置き換えてください。 String tableName = "<TABLE_NAME>"; // [必須] ご利用の多次元インデックス名に置き換えてください。 String indexName = "<SEARCH_INDEX_NAME>"; try { // SearchQuery の構築:メインクエリとフィルター条件。 SearchQuery searchQuery = SearchQuery.newBuilder() .query(QueryBuilders.terms("col_keyword").terms("value")) // キーワードの完全一致。 .filter(SearchFilter.newBuilder() .query(QueryBuilders.range("col_long") .greaterThan(1) // 範囲 (1, 10)。 .lessThan(10)) .build()) // .trackTotalCount(SearchQuery.TRACK_TOTAL_COUNT) // 必要に応じて、一致した合計数の統計を有効にします。 .build(); // リクエストの構築。 SearchRequest searchRequest = new SearchRequest(tableName, indexName, searchQuery); // デフォルトでは、プライマリキー列のみが返されます。必要に応じて返す列を設定します。 SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet(); // 多次元インデックスからすべての列を返すように設定します。 columnsToGet.setReturnAllFromIndex(true); searchRequest.setColumnsToGet(columnsToGet); SearchResponse resp = client.search(searchRequest); System.out.println("行: " + resp.getRows()); } catch (Exception e) { System.err.println("検索リクエストに失敗しました: " + e.getMessage()); } }