固定評分查詢
固定評分查詢(ConstScoreQuery)將子查詢封裝為過濾條件,所有命中文檔統一返回固定相關性分數 1.0,不再按 BM25 等演算法計算評分。
前提條件
已初始化 Tablestore Client。具體操作,請參見初始化 Tablestore Client。
已建立資料表並寫入資料。
已在資料表上建立多元索引。具體操作,請參見建立多元索引。
參數說明
參數 | 說明 |
| 資料表名稱。 |
| 多元索引名稱。 |
| 設定查詢類型為 |
| 內部子查詢條件,支援任意一種 Query 類型。 |
| 本次查詢返回的最大行數。如果僅需統計行數而不需要具體資料,可設定 |
| 是否返回所有列,包含 |
樣本
基本用法
使用 ConstScoreQuery 包裹 MatchQuery,對 Col_Text 列匹配關鍵詞 tablestore,所有命中文檔統一返回固定相關性分 1.0。按 score 降序排序便於驗證固定分效果。
/**
* 通過 ConstScoreQuery 進行固定評分查詢。
* 所有命中文檔的 score 均為 1.0,不受文本長度、詞頻等因素影響。
*/
func constScoreQuery(client *tablestore.TableStoreClient) {
// 構造內部子查詢:MatchQuery,對 Col_Text 列匹配關鍵詞 tablestore。
// 用 ConstScoreQuery 包裹 MatchQuery,所有命中文檔統一返回固定相關性分 1.0。
query := &search.ConstScoreQuery{
Filter: &search.MatchQuery{
FieldName: "Col_Text",
Text: "tablestore",
},
}
searchQuery := search.NewSearchQuery()
searchQuery.SetQuery(query)
searchQuery.SetLimit(20)
// searchQuery.SetGetTotalCount(true) // 設定返回匹配的總行數。
// 按 score 排序,便於驗證固定分效果。
searchQuery.SetSort(&search.Sort{
Sorters: []search.Sorter{
&search.ScoreSort{Order: search.SortOrder_DESC.Enum()},
},
})
searchRequest := &tablestore.SearchRequest{}
searchRequest.SetTableName("<TABLE_NAME>")
searchRequest.SetIndexName("<SEARCH_INDEX_NAME>")
searchRequest.SetSearchQuery(searchQuery)
resp, err := client.Search(searchRequest)
if err != nil {
fmt.Printf("%#v\n", err)
return
}
fmt.Println("RowCount:", len(resp.Rows))
// 驗證所有命中文檔的 score 均為 1.0。
for _, row := range resp.Rows {
jsonBody, _ := json.Marshal(row)
fmt.Println("Row:", string(jsonBody))
}
}返回指定列
預設僅返回主鍵列。通過 ColumnsToGet 可指定返回所有列或自訂返回列。在基本用法的 searchRequest 構造完成後追加以下代碼。
// 通過 ColumnsToGet 控制返回列。預設僅返回主鍵列。
// 方式一:返回所有列。
searchRequest.SetColumnsToGet(&tablestore.ColumnsToGet{ReturnAll: true})
// 方式二:返回指定列。
// searchRequest.SetColumnsToGet(&tablestore.ColumnsToGet{Columns: []string{"Col_Text", "Col_Keyword"}})
resp, err := client.Search(searchRequest)
if err != nil {
fmt.Printf("%#v\n", err)
return
}
fmt.Println("RowCount:", len(resp.Rows))
for _, row := range resp.Rows {
jsonBody, _ := json.Marshal(row)
fmt.Println("Row:", string(jsonBody))
}在 BoolQuery 中組合使用
以下樣本在 BoolQuery 的 MustQueries 中同時使用 ConstScoreQuery 和 MatchQuery:ConstScoreQuery 包裹 TermQuery,貢獻固定分數 1.0;MatchQuery 參與 BM25 評分。最終分數 = 1.0 + BM25 分數。
func constScoreInBoolQuery(client *tablestore.TableStoreClient) {
// 子查詢一:ConstScoreQuery 包裹 TermQuery,對 status 欄位做精確過濾,貢獻固定分 1.0。
constScoreQuery := &search.ConstScoreQuery{
Filter: &search.TermQuery{
FieldName: "status",
Term: "active",
},
}
// 子查詢二:MatchQuery,對 title 欄位正常參與 BM25 評分。
matchQuery := &search.MatchQuery{
FieldName: "title",
Text: "tablestore",
}
// 構造 BoolQuery,MustQueries 中同時包含 ConstScoreQuery 與 MatchQuery。
// 最終 score = ConstScoreQuery 固定分(1.0) + MatchQuery 的 BM25 分數。
boolQuery := &search.BoolQuery{
MustQueries: []search.Query{
constScoreQuery,
matchQuery,
},
}
searchQuery := search.NewSearchQuery()
searchQuery.SetQuery(boolQuery)
searchQuery.SetLimit(20)
// searchQuery.SetGetTotalCount(true) // 設定返回匹配的總行數。
searchQuery.SetSort(&search.Sort{
Sorters: []search.Sorter{
&search.ScoreSort{Order: search.SortOrder_DESC.Enum()},
},
})
searchRequest := &tablestore.SearchRequest{}
searchRequest.SetTableName("<TABLE_NAME>")
searchRequest.SetIndexName("<SEARCH_INDEX_NAME>")
searchRequest.SetSearchQuery(searchQuery)
resp, err := client.Search(searchRequest)
if err != nil {
fmt.Printf("%#v\n", err)
return
}
fmt.Println("RowCount:", len(resp.Rows))
for _, row := range resp.Rows {
jsonBody, _ := json.Marshal(row)
fmt.Println("Row:", string(jsonBody))
}
}與 ParallelScan 組合使用
在並發匯出情境中使用 ConstScoreQuery 作為 ScanQuery 的查詢條件,避免在匯出時計算 BM25 分數。完整並發流程請參見並發匯出資料。
func constScoreInParallelScan(client *tablestore.TableStoreClient, sessionId []byte) {
// 構造 ConstScoreQuery 包裹 MatchQuery,所有命中文檔統一返回固定相關性分 1.0。
constScoreQuery := &search.ConstScoreQuery{
Filter: &search.MatchQuery{
FieldName: "Col_Text",
Text: "tablestore",
},
}
// 構造 ScanQuery,將 ConstScoreQuery 作為查詢條件。
scanQuery := search.NewScanQuery().
SetQuery(constScoreQuery).
SetLimit(2000)
scanRequest := &tablestore.ParallelScanRequest{}
scanRequest.SetTableName("<TABLE_NAME>")
scanRequest.SetIndexName("<SEARCH_INDEX_NAME>")
scanRequest.SetScanQuery(scanQuery)
scanRequest.SetSessionId(sessionId) // 由 ComputeSplits 介面擷取,類型為 []byte,各 worker 共用同一 sessionId,用戶端按 splitsSize 隱式分發並發任務。
scanResponse, err := client.ParallelScan(scanRequest)
if err != nil {
fmt.Printf("%#v\n", err)
return
}
fmt.Println("RowCount:", len(scanResponse.Rows))
for _, row := range scanResponse.Rows {
jsonBody, _ := json.Marshal(row)
fmt.Println("Row:", string(jsonBody))
}
}