固定評分查詢
使用 Tablestore Java SDK 提供的 ConstScoreQuery,將子查詢封裝為過濾條件,讓所有命中文檔統一返回固定相關性分 1.0。適用於 BoolQuery 嵌套、ParallelScan 並發掃描等不依賴 BM25 評分的查詢情境。
前提條件
已初始化 Tablestore 用戶端,本文樣本中以
client表示。具體操作,請參見初始化 Tablestore Client。已在資料表上建立多元索引。具體操作,請參見建立多元索引。
參數說明
ConstScoreQuery 實現 Query 介面。通過 setFilter 設定內部子查詢,命中該子查詢的文檔統一返回固定相關性分 1.0。在外層調用 SearchQuery.setQuery 將 ConstScoreQuery 設為查詢條件。
public class ConstScoreQuery implements Query {
public void setFilter(Query filter);
}下表中 filter 為 ConstScoreQuery 的參數;tableName、indexName 通過 SearchRequest 設定;limit、columnsToGet 通過 SearchQuery 與 SearchRequest 設定。
參數 | 類型 | 說明 |
filter(必選) | Query |
|
tableName(必選) | String | 資料表名稱。 |
indexName(必選) | String | 多元索引名稱。 |
limit(可選) | int | 本次查詢返回的最大行數,預設 10。 |
columnsToGet(可選) | ColumnsToGet | 返回列設定,包括 |
SearchResponse 傳回值欄位:
欄位 | 類型 | 說明 |
| List<Row> | 命中文檔的主鍵列與屬性列,返回內容受 |
| List<SearchHit> | 命中文檔列表,每個元素包含 |
| long | 命中總行數,僅當 |
調用 client.search 時可能拋出的異常:
異常類 | 觸發情境 |
| 服務端業務錯誤,如資料表或多元索引不存在、參數非法、欄位類型不符等。 |
| 用戶端錯誤,如網路異常、序列化失敗、請求逾時等。 |
發生異常時,根據返回的錯誤資訊和錯誤碼定位問題。
樣本
基本用法
以下樣本對 Col_Text 欄位執行 ConstScoreQuery 包裹的 MatchQuery,所有命中文檔的相關性分均為 1.0。
// 構造內部子查詢:MatchQuery,對 Col_Text 列匹配關鍵詞 tablestore。
MatchQuery matchQuery = new MatchQuery();
matchQuery.setFieldName("Col_Text");
matchQuery.setText("tablestore");
// 用 ConstScoreQuery 包裹 MatchQuery,命中文檔統一返回固定相關性分 1.0。
ConstScoreQuery constScoreQuery = new ConstScoreQuery();
constScoreQuery.setFilter(matchQuery);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(constScoreQuery);
searchQuery.setLimit(20);
// searchQuery.setGetTotalCount(true); // 啟用返回總行數,會影響查詢效能。
// 按 score 排序,便於驗證固定相關性分效果。
searchQuery.setSort(new Sort(Collections.singletonList(new ScoreSort())));
SearchRequest searchRequest = new SearchRequest("example_table", "example_search_index", searchQuery);
SearchResponse resp = client.search(searchRequest);
System.out.println("Row: " + resp.getRows());
// 驗證所有命中文檔的 score 均為 1.0。
for (SearchHit hit : resp.getSearchHits()) {
System.out.println("Score: " + hit.getScore());
}返回指定列
通過 columnsToGet 控制返回列。預設僅返回主鍵列;可指定返回所有列或部分屬性列。
// 在「基本用法」的 searchRequest 基礎上追加 columnsToGet 設定。
SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
columnsToGet.setReturnAll(true);
// columnsToGet.setColumns(Arrays.asList("ColName1", "ColName2")); // 指定返回部分屬性列。
searchRequest.setColumnsToGet(columnsToGet);
SearchResponse resp = client.search(searchRequest);
System.out.println("Row: " + resp.getRows());與 BoolQuery 組合
在 BoolQuery.mustQueries 中加入 ConstScoreQuery 子查詢,讓該子句的相關性分恒定為 1.0;其他 MatchQuery 等子句正常參與 BM25 評分。最終文檔分數為各子句分數之和。
// 子查詢一:ConstScoreQuery 包裹 TermQuery,對 status 欄位做精確過濾,貢獻固定相關性分 1.0。
TermQuery termQuery = new TermQuery();
termQuery.setFieldName("status");
termQuery.setTerm(ColumnValue.fromString("active"));
ConstScoreQuery constScoreQuery = new ConstScoreQuery();
constScoreQuery.setFilter(termQuery);
// 子查詢二:MatchQuery,對 title 欄位正常參與 BM25 評分。
MatchQuery matchQuery = new MatchQuery();
matchQuery.setFieldName("title");
matchQuery.setText("tablestore");
// 構造 BoolQuery,mustQueries 中同時包含 ConstScoreQuery 與 MatchQuery。
// 最終 score = ConstScoreQuery 的固定相關性分(1.0) + MatchQuery 的 BM25 分數。
BoolQuery boolQuery = new BoolQuery();
boolQuery.setMustQueries(Arrays.asList(constScoreQuery, matchQuery));
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(boolQuery);
searchQuery.setSort(new Sort(Collections.singletonList(new ScoreSort())));
SearchRequest searchRequest = new SearchRequest("example_table", "example_search_index", searchQuery);
SearchResponse resp = client.search(searchRequest);
System.out.println("Row: " + resp.getRows());如需瞭解 BoolQuery 的完整用法,請參見多條件組合查詢。
與 ParallelScan 組合
ParallelScan 用於並發匯出多元索引資料。將 ConstScoreQuery 作為 ScanQuery 的查詢條件,可在並發掃描情境下統一返回固定相關性分 1.0,避免相關性評分的計算開銷。
// 複用「基本用法」中構造的 constScoreQuery(ConstScoreQuery 包裹 MatchQuery)。
ScanQuery scanQuery = new ScanQuery();
scanQuery.setQuery(constScoreQuery);
scanQuery.setLimit(2000);
ParallelScanRequest scanRequest = new ParallelScanRequest();
scanRequest.setTableName("example_table");
scanRequest.setIndexName("example_search_index");
scanRequest.setScanQuery(scanQuery);
scanRequest.setSessionId(sessionId); // 由 ComputeSplits 介面擷取,類型為 byte[],各 worker 共用同一 sessionId,用戶端按 splitsSize 隱式分發並發任務。
ParallelScanResponse scanResponse = client.parallelScan(scanRequest);
System.out.println("Row: " + scanResponse.getRows());sessionId 的擷取方法與並發匯出完整流程,請參見並發匯出資料。