This topic describes the sorting and paging methods in search index-based queries.

IndexSort

The matched data is sorted based on the value of the IndexSort field value when search index-based queries are used. Search indexes of the NESTED type do not support IndexSort. You can specify the IndexSort field when you create a search index. IndexSort determines the order of the data that Tablestore returns in search index-based queries. If you do not specify the IndexSort field, Tablestore returns the query result based on the order of primary key columns.

Specify a sorting method

You can specify a sorting method for each query. Search index-based queries support the following sorting methods. You can also specify multiple sorting methods with different priorities as needed.

ScoreSort

You can use ScoreSort to sort the query result by keyword relevance score. ScoreSort is applicable to scenarios such as full-text indexing.

Note You must set ScoreSort to sort the query result by keyword relevance score. Otherwise, the query result is sorted based on the value of the IndexSort field.
    searchQuery := search.NewSearchQuery()
    searchQuery.SetSort(&search.Sort{
        []search.Sorter{
            &search.ScoreSort{
Order: search.SortOrder_DESC.Enum(), // Sort the query result in descending order of scores.            },
        },
    })
PrimaryKeySort

You can use PrimaryKeySort to sort the query result based on the order of primary key columns.

searchQuery := search.NewSearchQuery()
    searchQuery.SetSort(&search.Sort{
        []search.Sorter{
            &search.PrimaryKeySort{
                Order: search.SortOrder_ASC.Enum(),
            },
        },
    })
FieldSort

You can use FieldSort to sort the query result based on the order of a specified column.

// Sort the query result by Col_Long in descending order.    searchQuery.SetSort(&search.Sort{
        []search.Sorter{
            &search.FieldSort{
                FieldName: "Col_Long",
                Order:     search.SortOrder_DESC.Enum(),
            },
        },
    })

You can sort the query result based on the order of multiple columns.

searchQuery.SetSort(&search.Sort{
        []search.Sorter{
            &search.FieldSort{
                FieldName: "col1",
                Order:     search.SortOrder_ASC.Enum(),
            },
            &search.FieldSort{
                FieldName: "col2",
                Order:     search.SortOrder_DESC.Enum(),
            },
        },
    })
GeoDistanceSort

You can use GeoDistanceSort to sort the query result based on distances of geographical locations.

    searchQuery.SetSort(&search.Sort{
        []search.Sorter{
            &search.GeoDistanceSort{
FieldName: "location",   // Set the name of the geographical location field. Points:    []string{"40,-70"}, // Set the coordinates of a central point.            },
        },
    })

Specify a paging method

Use the Limit and Offset parameters

When the total number of rows to obtain is smaller than 2,000, you can specify the Limit and Offset parameters for paging. For example, you can set Limit to 10 and Offset to 10 to obtain 10 rows of data starting from Row 10. The sum of the Limit and Offset parameter values cannot exceed 2,000.

searchQuery := search.NewSearchQuery()
searchQuery.SetLimit(10)
searchQuery.SetOffset(10) 
Use a token

If Tablestore does not complete reading all required data, Tablestore returns NextToken. You can use NextToken to continue reading the subsequent data. You cannot set the sorting method if you use a token. When you use the token, the sorting method is the same as that used in the previous request. The system sorts data based on the IndexSort field by default or based on the method that you have specified. Additionally, you cannot set Offset when a token is used. Data is scanned page by page, which results in a slow query.

/**
 * Use a token to read data by page.
 * If SearchResponse returns NextToken, you can use this token to initiate the next query. * All data that matches the filtering condition is returned until the NextToken field value is nil. */
func QueryRowsWithToken(client *tablestore.TableStoreClient, tableName string, indexName string) {
    querys := []search.Query{
        &search.MatchAllQuery{},
        &search.TermQuery{
            FieldName: "Col_Keyword",
            Term:      "tablestore",
        },
    }
    for _, query := range querys {
        fmt.Printf("Test query: %#v\n", query)
        searchRequest := &tablestore.SearchRequest{}
        searchRequest.SetTableName(tableName)
        searchRequest.SetIndexName(indexName)
        searchQuery := search.NewSearchQuery()
        searchQuery.SetQuery(query)
        searchQuery.SetLimit(10)
        searchQuery.SetGetTotalCount(true)
        searchRequest.SetSearchQuery(searchQuery)
        searchResponse, err := client.Search(searchRequest)
        if err ! = nil {
            fmt.Printf("%#v", err)
            return
        }
        rows := searchResponse.Rows
        requestCount := 1
        for searchResponse.NextToken ! = nil {
            searchQuery.SetToken(searchResponse.NextToken)
            searchResponse, err = client.Search(searchRequest)
            if err ! = nil {
                fmt.Printf("%#v", err)
                return
            }
            requestCount++
            for _, r := range searchResponse.Rows {
                rows = append(rows, r)
            }
        }
        fmt.Println("IsAllSuccess: ", searchResponse.IsAllSuccess)
        fmt.Println("TotalCount: ", searchResponse.TotalCount)
        fmt.Println("RowsSize: ", len(rows))
        fmt.Println("RequestCount: ", requestCount)
    }
}