Constant score query

更新时间:
复制 MD 格式

A constant score query (ConstScoreQuery) wraps a subquery and treats it as a filter. It returns every matched document with a fixed relevance score of 1.0, bypassing scoring algorithms such as BM25.

Prerequisites

Parameters

Parameter

Description

TableName

The name of the data table.

IndexName

The name of the Search Index.

Query

Sets the query type to ConstScoreQuery.

Filter

The subquery used as a filter. Supports any Query type. A ConstScoreQuery only checks whether a document matches. If it does, a fixed score of 1.0 is returned.

Limit

The maximum number of rows to return. To retrieve only the total row count without data, set Limit=0.

ColumnsToGet

The columns to return. Contains the ReturnAll and Columns sub-parameters. By default, ReturnAll is false and only primary key columns are returned. Use Columns to specify additional columns, or set ReturnAll to true to return all columns.

Examples

Basic usage

Wraps a MatchQuery in a ConstScoreQuery to find documents where the Col_Text column contains the keyword tablestore. All matched documents receive a fixed relevance score of 1.0. Results are sorted by score in descending order to demonstrate the fixed-score effect.

/**
 * Use ConstScoreQuery to perform a constant score query.
 * All matched documents have a score of 1.0, regardless of factors like text length or term frequency.
 */
func constScoreQuery(client *tablestore.TableStoreClient) {
	// Create the inner subquery: a MatchQuery that matches the keyword "tablestore" in the Col_Text column.
	// Wrap the MatchQuery in a ConstScoreQuery. All matched documents will receive a fixed relevance score of 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) // Set to return the total count of matched rows.
	// Sort by score to verify the effect of the fixed 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))
	// Verify that all matched documents have a score of 1.0.
	for _, row := range resp.Rows {
		jsonBody, _ := json.Marshal(row)
		fmt.Println("Row:", string(jsonBody))
	}
}

Return specified columns

By default, only primary key columns are returned. Use ColumnsToGet to return all columns or a custom set of columns. Add the following code after creating the searchRequest object in the basic usage example.

// Use ColumnsToGet to control which columns are returned. By default, only primary key columns are returned.
// Option 1: Return all columns.
searchRequest.SetColumnsToGet(&tablestore.ColumnsToGet{ReturnAll: true})
// Option 2: Return specified columns.
// 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))
}

Use with a BoolQuery

Combines a ConstScoreQuery and a MatchQuery in the MustQueries clause of a BoolQuery. The ConstScoreQuery wraps a TermQuery and contributes a fixed score of 1.0. The MatchQuery is scored by the BM25 algorithm. The final score is the sum of the ConstScoreQuery score (1.0) and the MatchQuery BM25 score.

func constScoreInBoolQuery(client *tablestore.TableStoreClient) {
    // Subquery 1: A ConstScoreQuery wraps a TermQuery to perform an exact match on the "status" field, contributing a fixed score of 1.0.
    constScoreQuery := &search.ConstScoreQuery{
        Filter: &search.TermQuery{
            FieldName: "status",
            Term:      "active",
        },
    }

    // Subquery 2: A MatchQuery that is scored using the BM25 algorithm on the "title" field.
    matchQuery := &search.MatchQuery{
        FieldName: "title",
        Text:      "tablestore",
    }

    // Create a BoolQuery that includes both the ConstScoreQuery and MatchQuery in its MustQueries clause.
    // The final score is the sum of the fixed score from ConstScoreQuery (1.0) and the BM25 score from the MatchQuery.
    boolQuery := &search.BoolQuery{
        MustQueries: []search.Query{
            constScoreQuery,
            matchQuery,
        },
    }

    searchQuery := search.NewSearchQuery()
    searchQuery.SetQuery(boolQuery)
    searchQuery.SetLimit(20)
    // searchQuery.SetGetTotalCount(true) // Set to return the total count of matched rows.
    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))
    }
}

Use with a ParallelScan

In concurrent export scenarios, use a ConstScoreQuery as the query condition for a ScanQuery to skip BM25 score calculation. For the complete concurrent export workflow, see Export data in parallel.

func constScoreInParallelScan(client *tablestore.TableStoreClient, sessionId []byte) {
	// Create a ConstScoreQuery that wraps a MatchQuery. All matched documents will receive a fixed relevance score of 1.0.
	constScoreQuery := &search.ConstScoreQuery{
		Filter: &search.MatchQuery{
			FieldName: "Col_Text",
			Text:      "tablestore",
		},
	}

	// Create a ScanQuery and set the ConstScoreQuery as its query condition.
	scanQuery := search.NewScanQuery().
		SetQuery(constScoreQuery).
		SetLimit(2000)

	scanRequest := &tablestore.ParallelScanRequest{}
	scanRequest.SetTableName("<TABLE_NAME>")
	scanRequest.SetIndexName("<SEARCH_INDEX_NAME>")
	scanRequest.SetScanQuery(scanQuery)
	// The session ID is obtained from the `ComputeSplits` API call. The type is `[]byte`. 
	// All workers share the same session ID. The client uses `splitsSize` to implicitly distribute concurrent tasks.
	scanRequest.SetSessionId(sessionId) 

	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))
	}
}