查詢後過濾(Filter)是Table Store多元索引(Search Index)新增的一種查詢協助工具功能,支援對 Query 結果再做一次過濾。該功能的目的主要是人工幹預內部的查詢最佳化工具,強制某些查詢條件在最後階段執行,使用合理,可以大幅提高查詢效能。
Java SDK從5.17.5版本開始支援查詢後過濾功能,如需使用請聯絡Table Store支援人員開通。
功能架構
查詢後過濾基於多層查詢架構實現:
SearchRequest:查詢請求的頂層容器,包含表名、索引名和具體的查詢配置。
SearchQuery:核心查詢配置,包含主查詢條件(Query)和可選的查詢過濾器(SearchFilter)。
Query:主查詢條件,支援多元索引的所有查詢類型和資料類型,用於初次資料檢索。
SearchFilter:二次過濾器,包含過濾查詢條件,在主查詢結果基礎上進行精細化篩選。
使用限制
必須與多元索引查詢條件組合使用,支援精確查詢(TermQuery)、多詞精確查詢(TermsQuery)、範圍查詢(RangeQuery)、列存在性查詢(ExistsQuery)及其組合查詢(BoolQuery)。
BoolQuery 查詢時,僅支援必須匹配(mustQueries)、必須不匹配(mustNotQueries)、可選匹配(shouldQueries)子句,不支援過濾子句(filterQueries)。
僅支援對不可分詞字串(Keyword)、長整型(Long)、雙精確度浮點型(Double)欄位進行過濾,且欄位必須啟用排序統計(enableSortAndAgg)屬性。
查詢後過濾不支援設定權重。
前提條件
在資料表上建立多元索引。
方法說明
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)); // 組裝 Filter 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("Rows: " + resp.getRows()); } catch (Exception e) { System.err.println("Search failed: " + 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("Total Count (matched): " + resp.getTotalCount());
構建器模式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("Rows: " + resp.getRows()); } catch (Exception e) { System.err.println("Search request failed: " + e.getMessage()); } }