Todos os produtos
Search
Central de documentação

Tablestore:Sorting and paging

Última atualização: Jul 03, 2026

Ao consultar dados em um índice de busca, ordene os resultados com base em uma ordem predefinida ou especificada no momento da consulta. Para grandes conjuntos de resultados, use a paginação baseada em deslocamento (offset) ou em token para localizar rapidamente os dados necessários.

Casos de uso

Categoria

Método

Recurso

Caso de uso

Ordenação

Defina na criação

Pré-ordenação de índice (IndexSort)

Por padrão, o Tablestore ordena os dados em um índice de busca usando o método de pré-ordenação de índice (IndexSort) configurado. Isso define a ordem de classificação padrão dos resultados retornados.

Defina na consulta

ScoreSort (ordenação por pontuação de relevância)

Ordena os resultados da consulta pela pontuação de relevância, calculada pelo algoritmo BM25. Ideal para cenários baseados em relevância, como busca de texto completo.

PrimaryKeySort (ordenação por chave primária)

Classifica os resultados pela chave primária. Útil para organizar itens pelos identificadores exclusivos.

FieldSort (ordenação por campo)

Organiza os resultados pelo valor do campo. Aplicável a cenários de e-commerce ou redes sociais, nos quais a ordenação ocorre por atributos como volume de vendas ou visualizações de página.

Para campos com múltiplos valores, como campos do tipo array ou nested, use o parâmetro mode para controlar qual elemento será usado na ordenação.

GeoDistanceSort (ordenação por distância geográfica)

Classifica os resultados pela distância de um ponto geográfico. Adequado para serviços baseados em localização, como mapas ou logística; por exemplo, ordenar restaurantes próximos por distância.

Paginação

Defina na consulta

Usar paginação baseada em deslocamento

Use a paginação baseada em deslocamento quando o número total de linhas a recuperar for inferior a 100.000.

Usar paginação baseada em token

Use a paginação baseada em token para recuperar sequencialmente grandes conjuntos de resultados. Por padrão, a navegação ocorre apenas para frente. No entanto, como o token permanece válido durante todo o processo de consulta, armazene em cache um token anterior para paginar para trás.

SDKs

Implemente a ordenação e a paginação usando os SDKs das linguagens a seguir.

Pré-ordenação de índice

Por padrão, o Tablestore organiza os dados em um índice de busca com base em uma ordem predefinida, denominada pré-ordenação de índice (IndexSort). Durante a consulta de dados, o IndexSort determina a ordem padrão dos resultados retornados.

Ao criar um índice de busca, personalize o IndexSort. Se você não especificar essa configuração, o índice adotará a ordenação por chave primária como padrão.

Importante
  • A pré-ordenação de índice suporta apenas PrimaryKeySort (ordenação por chave primária) e FieldSort (ordenação por campo).

  • Não use a pré-ordenação de índice em um índice de busca que contenha campos do tipo nested.

  • Após criar um índice de busca, use o recurso de modificação dinâmica de esquema para alterar as configurações de IndexSort.

Ordenação no momento da consulta

Ordene apenas campos cuja propriedade enableSortAndAgg esteja definida como true.

Especifique um método de ordenação para cada consulta. Um índice de busca suporta os quatro tipos de classificadores a seguir. Combine vários classificadores para ordenar os resultados com base em uma sequência de critérios.

ScoreSort

Classifica os resultados da consulta pela pontuação de relevância, calculada pelo algoritmo BM25. Este método é adequado para cenários baseados em relevância, como busca de texto completo.

Importante
  • Para ordenar por pontuação de relevância, especifique explicitamente o ScoreSort. Caso contrário, o Tablestore classificará os resultados conforme as configurações de IndexSort do índice.

  • Ao usar o ScoreSort, campos do tipo FuzzyKeyword não são incluídos na ordenação, e o parâmetro weight não tem efeito sobre esses campos.

SearchQuery searchQuery = new SearchQuery();
searchQuery.setSort(new Sort(Arrays.asList(new ScoreSort())));

PrimaryKeySort

Ordena os resultados pela chave primária.

SearchQuery searchQuery = new SearchQuery();
searchQuery.setSort(new Sort(Arrays.asList(new PrimaryKeySort()))); // In ascending order.
//searchQuery.setSort(new Sort(Arrays.asList(new PrimaryKeySort(SortOrder.DESC)))); // In descending order.

FieldSort

Classifica os resultados pelo valor do campo.

Ordenação por campo único

Organiza os resultados com base nos valores de um único campo.

SearchQuery searchQuery = new SearchQuery();
searchQuery.setSort(new Sort(Arrays.asList(new FieldSort("col", SortOrder.ASC))));

Ordenação por múltiplos campos

Classifica os resultados primeiramente pelos valores de um campo e, em seguida, pelos valores de outro campo.

SearchQuery searchQuery = new SearchQuery();
searchQuery.setSort(new Sort(Arrays.asList(
    new FieldSort("col1", SortOrder.ASC), new FieldSort("col2", SortOrder.ASC))));

Campo de fallback

Ao ordenar por um campo do tipo Long, Double ou Date, defina o parâmetro missingField. Esse parâmetro especifica outro campo do mesmo tipo a ser usado como valor de fallback para ordenação caso uma linha não possua valor no campo de ordenação principal.

/**
* Sort results in descending order based on the values in the Col_Long field. 
* If a row is missing a value in the Col_Long field (Long type), 
* the value from the Col_Long_sec field (Long type) is used for sorting instead.
*/
SearchQuery searchQuery = new SearchQuery();
FieldSort fieldSort = new FieldSort("Col_Long");
// Specify the Col_Long_sec field as the fallback for sorting when a value is missing in the Col_Long field.
fieldSort.setMissingField("Col_Long_sec");
fieldSort.setOrder(SortOrder.DESC); 

Valores ausentes

O parâmetro missingValue define a posição de ordenação para documentos sem o campo de classificação. Configure esse parâmetro para controlar onde esses documentos aparecerão nos resultados.

O comportamento da ordenação é o seguinte:

  • Se missingValue for definido como FieldSort.FIRST_WHEN_MISSING, os documentos com valores ausentes serão sempre colocados no início dos resultados, independentemente da ordem de classificação (ascendente ou descendente).

  • Caso missingValue seja definido como FieldSort.LAST_WHEN_MISSING ou null, os documentos com valores ausentes serão sempre posicionados ao final dos resultados, independentemente da ordem de classificação.

    /**
    * Sort results in descending order based on the values in the Col_Long field (Long type).
    * If a row is missing a value in the Col_Long field, place that document at the beginning of the results.
    */
    SearchQuery searchQuery = new SearchQuery();
    FieldSort fieldSort = new FieldSort("Col_Long");
    // Place documents with missing values first.
    fieldSort.setMissingValue(FieldSort.FIRST_WHEN_MISSING);
    fieldSort.setOrder(SortOrder.DESC);
    searchQuery.setSort(new Sort(Arrays.asList(fieldSort)));

Campos com múltiplos valores

Para campos com múltiplos valores, como campos do tipo array ou nested, use o parâmetro mode para especificar qual elemento deve ser usado na ordenação.

Ordene por um valor específico em um array com múltiplos valores.

// Assume you have two rows, doc1 and doc2. Both have a field1 of array type.
// The value of field1 in doc1 is [2,3]. The value of field1 in doc2 is [1,3,4].
// You can set the mode parameter to specify which value in the array to use for sorting.
{
    // When mode is set to SortMode.MAX, the sort order is doc2 (sorted by 4), then doc1 (sorted by 3).
    FieldSort fieldSort = new FieldSort("field1", SortOrder.DESC);
    fieldSort.setMode(SortMode.MAX);
}
{
    // When mode is set to SortMode.MIN, the sort order is doc1 (sorted by 2), then doc2 (sorted by 1).
    FieldSort fieldSort = new FieldSort("field1", SortOrder.DESC);
    fieldSort.setMode(SortMode.MIN);
}

Também é possível ordenar as sublinhas de um campo do tipo nested.

// Assume you have two rows, doc1 and doc2. Both have a field1 of nested type.
// The value of field1 in doc1 is [{"name":"b", "age":1},{"name":"a", "age":7}].
// The value of field1 in doc2 is [{"name":"a", "age":1},{"name":"c", "age":1},{"name":"d", "age":5}].

{
    // Sort all sub-rows and use the mode parameter to specify which value to use for sorting.
    // When mode is set to SortMode.MAX and you sort by the age field, the result is doc1 (sorted by 7), then doc2 (sorted by 5).
    FieldSort fieldSort = new FieldSort("field1.age", SortOrder.DESC);
    fieldSort.setMode(SortMode.MAX);
    String path = "field1";
    NestedFilter nestedFilter = new NestedFilter(path, QueryBuilders.matchAll().build());
    fieldSort.setNestedFilter(nestedFilter);
}
{
    // Sort only the sub-rows where age=1, and use the mode parameter to specify which value to use.
    {
        // When mode is set to SortMode.MAX and you sort by the name field, the result is doc2 (sorted by "c"), then doc1 (sorted by "b").
        FieldSort fieldSort = new FieldSort("field1.name", SortOrder.DESC);
        fieldSort.setMode(SortMode.MAX);
        String path = "field1";
        NestedFilter nestedFilter = new NestedFilter(path, QueryBuilders.term("field1.age",1).build());
        fieldSort.setNestedFilter(nestedFilter);
    }
    {
        // When mode is set to SortMode.MIN and you sort by the name field, the result is doc1 (sorted by "b"), then doc2 (sorted by "a").
        FieldSort fieldSort = new FieldSort("field1.name", SortOrder.DESC);
        fieldSort.setMode(SortMode.MIN);
        String path = "field1";
        NestedFilter nestedFilter = new NestedFilter(path, QueryBuilders.term("field1.age",1).build());
        fieldSort.setNestedFilter(nestedFilter);
    }
}

GeoDistanceSort

Ordena os resultados pela distância de um ponto geográfico.

SearchQuery searchQuery = new SearchQuery();
// The 'geo' field is of the GeoPoint type. Sort results by the distance
// from the value in this field to the point "0,0".
Sort.Sorter sorter = new GeoDistanceSort("geo", Arrays.asList("0, 0"));
searchQuery.setSort(new Sort(Arrays.asList(sorter)));

Métodos de paginação

Para paginar pelos resultados da consulta, use os parâmetros limit e offset ou um token.

Paginação baseada em deslocamento

Use a paginação baseada em deslocamento quando o número total de linhas a recuperar for inferior a 100.000. A soma de limit e offset deve ser menor ou igual a 100.000, e o valor máximo para limit é 100.

Nota

Para aumentar o limiar de limit, consulte Como aumento o limite da API de busca para 1.000?.

Se os parâmetros limit e offset não forem definidos, limit assumirá o valor padrão 10 e offset assumirá o valor padrão 0.

SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setLimit(100);
searchQuery.setOffset(100);

Paginação baseada em token

A paginação baseada em token é recomendada para paginação profunda, pois não possui limite de profundidade.

Se uma resposta não contiver todos os dados correspondentes, o servidor retornará um nextToken.

Por padrão, a paginação baseada em token permite apenas avançar pelos resultados. No entanto, como o token permanece válido durante todo o processo de consulta, armazene em cache um token anterior para paginar para trás.

Importante

Caso precise persistir um nextToken ou enviá-lo a uma aplicação front-end, use Base64 para codificá-lo em uma string. O token é um array de bytes, não uma string. Convertê-lo diretamente para string com new String(nextToken) causa perda de dados.

Ao paginar com um token, a ordem de classificação é a mesma da solicitação anterior, seja usando o IndexSort padrão ou uma ordenação personalizada. Portanto, não defina um parâmetro Sort ao usar um token. Também não defina um offset, pois a leitura dos dados ocorre apenas de forma sequencial.

Importante

Um índice de busca que contém um campo do tipo nested não suporta pré-ordenação de índice. Se precisar paginar pelos resultados desse índice, especifique uma ordem de classificação na consulta. Caso contrário, o servidor não retornará um nextToken, mesmo que haja mais dados disponíveis.

private static void readMoreRowsWithToken(SyncClient client) {
    SearchQuery searchQuery = new SearchQuery();
    searchQuery.setQuery(new MatchAllQuery());
    searchQuery.setGetTotalCount(true);// Set to return the total count of matched rows.
    // Specify the data table name (for example, sampleTable) and the search index name (for example, sampleSearchIndex). 
    // You can find the search index name on the Index Management tab for the table in the Tablestore console, or by listing search indexes with the SDK.
    SearchRequest searchRequest = new SearchRequest("sampleTable", "sampleSearchIndex", searchQuery);

    SearchResponse resp = client.search(searchRequest);
    if (!resp.isAllSuccess()) {
        throw new RuntimeException("not all success");
    }
    List<Row> rows = resp.getRows();
    while (resp.getNextToken()!=null) { // A null nextToken means all data has been read.
        // Get the nextToken.
        byte[] nextToken = resp.getNextToken();

        {
            // If you need to persist the nextToken or send it to a front-end application, 
            // use Base64 to encode the nextToken into a string for storage and transfer.
            // A token is a byte array. Directly using new String(nextToken) will cause data loss.
            String tokenAsString = Base64.toBase64String(nextToken);
            // Decode the string back to a byte array.
            byte[] tokenAsByte = Base64.fromBase64String(tokenAsString);
        }

        // Set the token for the next request.
        searchRequest.getSearchQuery().setToken(nextToken);
        resp = client.search(searchRequest);
        if (!resp.isAllSuccess()) {
            throw new RuntimeException("not all success");
        }
        rows.addAll(resp.getRows());
    }
    System.out.println("RowSize: " + rows.size());
    System.out.println("TotalCount: " + resp.getTotalCount());// Prints the total number of matched rows, not the number of returned rows.
}