Ao consultar dados com um índice de busca, controle a ordem dos resultados definindo previamente um método de ordenação ou especificando-o durante a consulta. Se o conjunto de resultados for grande, use a paginação para navegar rapidamente até os dados necessários.
IndexSort
Por padrão, um índice de busca ordena os dados com base na configuração do IndexSort. Ao consultar dados com esse índice, o IndexSort determina a ordem padrão dos resultados.
Defina um IndexSort personalizado ao criar um índice de busca. Se nenhum IndexSort personalizado for especificado, a ordenação ocorrerá pela chave primária.
O
IndexSortaceita apenasPrimaryKeySort(ordenação por chave primária) eFieldSort(ordenação por valor de campo).Índices de busca com campos do tipo aninhado não aceitam
IndexSort.Após criar um índice de busca, use o recurso de modificação dinâmica de esquema para alterar a configuração de
IndexSort.
Ordenação no momento da consulta
A ordenação é suportada apenas para campos nos quais EnableSortAndAgg esteja definido como verdadeiro.
Especifique um método de ordenação para cada consulta. Um índice de busca aceita quatro tipos de classificadores. Combine vários classificadores para ordenar os resultados com base em uma sequência de critérios.
ScoreSort
Ordena os resultados pela pontuação de relevância, calculada com o algoritmo BM25. Este método é adequado para cenários que exigem classificação por relevância, como buscas de texto completo.
Para ordenar resultados pela pontuação de relevância, especifique explicitamente
ScoreSort. Caso contrário, os resultados serão ordenados com base na configuraçãoIndexSortdo índice.Ao usar
ScoreSort, campos FuzzyKeyword não são incluídos no processo de ordenação e o parâmetroweightnão tem efeito sobre esses campos.
searchQuery := search.NewSearchQuery()
searchQuery.SetSort(&search.Sort{
[]search.Sorter{
&search.ScoreSort{
Order: search.SortOrder_DESC.Enum(), // Sort in descending order of score.
},
},
})
PrimaryKeySort
Ordena os resultados pela primary key, o que é útil para organizar itens pelos identificadores únicos.
searchQuery := search.NewSearchQuery()
searchQuery.SetSort(&search.Sort{
[]search.Sorter{
&search.PrimaryKeySort{
Order: search.SortOrder_ASC.Enum(),
},
},
})
FieldSort
Ordena os resultados pelo valor de um field específico. Essa abordagem é útil em aplicações de e-commerce ou redes sociais, nas quais pode ser necessário ordenar itens por atributos como volume de vendas ou visualizações de página.
Ordenação por coluna única
Ordena os resultados com base nos valores de um único campo.
// Sort the results based on the Col_Long field in descending order.
searchQuery.SetSort(&search.Sort{
[]search.Sorter{
&search.FieldSort{
FieldName: "Col_Long",
Order: search.SortOrder_DESC.Enum(),
},
},
})
Ordenação por múltiplas colunas
Ordena os resultados primeiramente pelos valores de um campo e, em seguida, pelos valores de outro.
searchQuery.SetSort(&search.Sort{
[]search.Sorter{
&search.FieldSort{
FieldName: "col1",
Order: search.SortOrder_ASC.Enum(),
},
&search.FieldSort{
FieldName: "col2",
Order: search.SortOrder_DESC.Enum(),
},
},
})
Ordenação com valores ausentes
Quando um campo de ordenação está ausente em um documento, o parâmetro MissingValue determina sua posição nos resultados ordenados.
O comportamento da ordenação é o seguinte:
Se você definir
MissingValuecomosearch.FirstWhenMissing, os documentos sem o campo serão colocados no início, independentemente de a ordem de classificação ser ascendente (asc) ou descendente (desc).-
Caso defina
MissingValuecomosearch.LastWhenMissingounil, os documentos sem o campo serão colocados no final, independentemente da ordem de classificação.// Sort the results based on the view_at field in ascending order, // and place documents with missing values at the end. searchQuery.SetSort(&search.Sort{ []search.Sorter{ &search.FieldSort{ FieldName: "view_at", Order: search.SortOrder_ASC.Enum(), MissingValue: search.LastWhenMissing, }, }, })
GeoDistanceSort
Ordena os resultados pela distância de um ponto geográfico. Esse recurso é útil para aplicações de mapas e logística, como ordenar restaurantes próximos pela distância em relação à localização atual.
searchQuery.SetSort(&search.Sort{
[]search.Sorter{
&search.GeoDistanceSort{
FieldName: "location", // Specify the name of the GeoPoint field.
Points: []string{"40,-70"}, // Specify the center point.
},
},
})
Métodos de paginação
Para paginar os resultados, use os parâmetros Limit e Offset ou um token.
Paginação com Limit e Offset
Use Limit e Offset para paginação. A soma de Limit e Offset deve ser menor ou igual a 100.000, e o valor máximo para Limit é 100.
Para aumentar o limite superior do parâmetro Limit, consulte Como aumento o parâmetro limit para 1000 nas consultas de índice de busca?.
Se esses parâmetros não forem especificados, Limit assumirá o valor padrão 10 e Offset assumirá o valor padrão 0.
searchQuery := search.NewSearchQuery()
searchQuery.SetLimit(10)
searchQuery.SetOffset(10)
Paginação com token
Para paginação profunda, use um token, pois este método não possui limitações de profundidade.
Se uma consulta retornar mais resultados do que uma única resposta comporta, o servidor fornecerá um NextToken. Use esse token em uma solicitação subsequente para recuperar a próxima página.
Por padrão, a paginação baseada em token permite apenas avançar. No entanto, como um token permanece válido durante toda a sessão de consulta, armazene tokens anteriores em cache para implementar a paginação regressiva.
Se precisar persistir o NextToken ou enviá-lo a uma aplicação front-end, use a codificação Base64 para convertê-lo em uma string para armazenamento e transmissão. Como o token é um slice de bytes e não uma string, convertê-lo diretamente usando string(NextToken) resulta em perda de dados.
Ao usar um token, o método de ordenação da solicitação anterior é aplicado automaticamente. Portanto, não é possível especificar os parâmetros Sort ou Offset em uma solicitação baseada em token. Leia os dados sequencialmente, uma página por vez.
Índices de busca com campos do tipo aninhado não aceitam IndexSort. Por isso, especifique um método de ordenação na consulta para ativar a paginação. Sem uma ordem de classificação definida, o servidor não retornará um NextToken, mesmo que existam mais resultados.
/**
* Read data page by page by using a token.
* If a SearchResponse contains a NextToken, you can use it to initiate the next query.
* A nil NextToken indicates that all matching data has been retrieved.
*/
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 {
{
// To persist or send the NextToken, Base64-encode it.
// The token is a byte slice, not a string; direct conversion causes data loss.
tokenAsString := base64.StdEncoding.EncodeToString(searchResponse.NextToken)
// Decode the string back into a byte slice.
tokenAsByte, err := base64.StdEncoding.DecodeString(tokenAsString)
if err != nil {
fmt.Printf("len:%d, %#v",len(tokenAsByte), err)
return
}
}
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)
}
}