固定評分查詢

更新時間:
Copy as MD

使用 Tablestore Java SDK 提供的 ConstScoreQuery,將子查詢封裝為過濾條件,讓所有命中文檔統一返回固定相關性分 1.0。適用於 BoolQuery 嵌套、ParallelScan 並發掃描等不依賴 BM25 評分的查詢情境。

前提條件

參數說明

ConstScoreQuery 實現 Query 介面。通過 setFilter 設定內部子查詢,命中該子查詢的文檔統一返回固定相關性分 1.0。在外層調用 SearchQuery.setQueryConstScoreQuery 設為查詢條件。

public class ConstScoreQuery implements Query {
    public void setFilter(Query filter);
}

下表中 filterConstScoreQuery 的參數;tableNameindexName 通過 SearchRequest 設定;limitcolumnsToGet 通過 SearchQuerySearchRequest 設定。

參數

類型

說明

filter(必選)

Query

ConstScoreQuery 的內部子查詢條件,支援 MatchQueryTermQueryBoolQueryRangeQuery 等任意 Query 子類。僅判斷文檔是否命中該子查詢,命中即返回固定相關性分 1.0。

tableName(必選)

String

資料表名稱。

indexName(必選)

String

多元索引名稱。

limit(可選)

int

本次查詢返回的最大行數,預設 10。

columnsToGet(可選)

ColumnsToGet

返回列設定,包括 returnAllcolumnsreturnAll 預設為 false,此時通過 columns 指定返回的列;如未指定 columns,則只返回主鍵列。設定 returnAlltrue 時,返回所有列。

SearchResponse 傳回值欄位:

欄位

類型

說明

getRows()

List<Row>

命中文檔的主鍵列與屬性列,返回內容受 columnsToGet 控制。

getSearchHits()

List<SearchHit>

命中文檔列表,每個元素包含 score 等元資訊。固定評分查詢情境下所有元素的 score 均為 1.0。

getTotalCount()

long

命中總行數,僅當 searchQuery.setGetTotalCount(true) 時有效,影響查詢效能。

調用 client.search 時可能拋出的異常:

異常類

觸發情境

TableStoreException

服務端業務錯誤,如資料表或多元索引不存在、參數非法、欄位類型不符等。

ClientException

用戶端錯誤,如網路異常、序列化失敗、請求逾時等。

發生異常時,根據返回的錯誤資訊和錯誤碼定位問題。

樣本

基本用法

以下樣本對 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 的擷取方法與並發匯出完整流程,請參見並發匯出資料