Todos los productos
Search
Centro de documentos

Tablestore:Sorting and paging

Última actualización: Sep 03, 2026

Al consultar datos desde un índice de búsqueda, puede ordenar los resultados mediante un orden predefinido o especificar uno al momento de la consulta. Para conjuntos de resultados grandes, utilice la paginación basada en desplazamiento o en token para encontrar rápidamente los datos que necesita.

Casos de uso

Categoría

Método

Función

Caso de uso

Ordenamiento

Definir al crear

Index presorting (IndexSort)

De forma predeterminada, Tablestore ordena los datos en un índice de búsqueda mediante el método de preordenamiento del índice configurado (IndexSort). Esto establece el orden de clasificación predeterminado para los resultados devueltos.

Definir durante la consulta

ScoreSort (relevance score sort)

Ordena los resultados de la consulta por puntuación de relevancia, calculada mediante el algoritmo BM25. Es adecuado para escenarios basados en relevancia, como la búsqueda de texto completo.

PrimaryKeySort (primary key sort)

Ordena los resultados por clave primaria. Resulta útil para clasificar elementos según sus identificadores únicos.

FieldSort (field sort)

Ordena los resultados por valor de campo. Es útil en escenarios de comercio electrónico o redes sociales donde se requiere ordenar por atributos como volumen de ventas o vistas de página.

Para campos con múltiples valores, como los de tipo matriz o anidado, puede usar el parámetro mode para controlar qué elemento se utiliza en la ordenación.

GeoDistanceSort (geo-distance sort)

Ordena los resultados según la distancia desde un punto geográfico. Es adecuado para servicios basados en ubicación, como mapas o logística; por ejemplo, para ordenar restaurantes cercanos por distancia.

Paginación

Definir durante la consulta

Use offset-based paging

Utilice la paginación basada en desplazamiento cuando el número total de filas a recuperar sea menor a 100,000.

Use token-based paging

Utilice la paginación basada en token para recuperar secuencialmente grandes conjuntos de resultados. De forma predeterminada, solo se permite avanzar. Sin embargo, dado que un token permanece válido durante todo el proceso de consulta, puede almacenar en caché un token anterior para retroceder.

SDKs

Puede implementar el ordenamiento y la paginación mediante los SDKs para los siguientes lenguajes.

Preordenamiento del índice

De forma predeterminada, Tablestore ordena los datos en un índice de búsqueda según un orden predefinido denominado preordenamiento del índice (IndexSort). Al consultar datos, IndexSort determina el orden predeterminado de los resultados devueltos.

Al crear un índice de búsqueda, puede personalizar IndexSort. Si no especifica esta configuración, el índice utilizará la ordenación por clave primaria de forma predeterminada.

Importante
  • El preordenamiento del índice solo admite PrimaryKeySort (ordenación por clave primaria) y FieldSort (ordenación por campo).

  • No se puede utilizar el preordenamiento del índice en un índice de búsqueda que contenga campos de tipo anidado.

  • Después de crear un índice de búsqueda, la función dynamic schema modification le permite modificar la configuración de IndexSort.

Ordenar durante la consulta

Solo puede ordenar por campos donde la propiedad enableSortAndAgg esté establecida en true.

Puede especificar un método de ordenamiento para cada consulta. Un índice de búsqueda admite los siguientes cuatro tipos de clasificadores. También puede usar varios clasificadores para ordenar los resultados según una secuencia de criterios.

ScoreSort

Ordena los resultados de la consulta por puntuación de relevancia, calculada mediante el algoritmo BM25. Este método es adecuado para escenarios basados en relevancia, como la búsqueda de texto completo.

Importante
  • Si desea ordenar por puntuación de relevancia, debe especificar explícitamente ScoreSort. De lo contrario, Tablestore ordenará los resultados según la configuración de IndexSort del índice.

  • Cuando utiliza ScoreSort, los campos de tipo FuzzyKeyword no se incluyen en la ordenación y el parámetro weight no tiene efecto sobre estos campos.

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

PrimaryKeySort

Ordena los resultados por clave primaria.

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

Ordena los resultados por valor de campo.

Ordenamiento por un solo campo

Ordena los resultados según los valores de un único campo.

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

Ordenamiento por múltiples campos

Ordena los resultados primero por los valores de un campo y luego por los valores de otro campo.

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

Campo alternativo

Al ordenar por un campo de tipo Long, Double o Date, puede establecer el parámetro missingField. Este parámetro especifica otro campo del mismo tipo que se usará como valor alternativo para la ordenación si a una fila le falta un valor en el campo de ordenación 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 faltantes

El parámetro missingValue especifica la posición de ordenación para los documentos a los que les falta el campo de ordenación. Puede configurar este parámetro para controlar dónde aparecen estos documentos en los resultados.

El comportamiento de ordenación es el siguiente:

  • Si establece missingValue en FieldSort.FIRST_WHEN_MISSING, los documentos con valores faltantes siempre se colocarán al principio de los resultados, independientemente del orden de clasificación (ascendente o descendente).

  • Si establece missingValue en FieldSort.LAST_WHEN_MISSING o null, los documentos con valores faltantes siempre se colocarán al final de los resultados, sin importar el orden de clasificación.

    /**
    * 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 con múltiples valores

Para campos con múltiples valores, como los de tipo matriz o anidado, puede usar el parámetro mode para especificar qué elemento se utilizará en la ordenación.

Ordene por un valor específico dentro de una matriz con múltiples 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);
}

También puede ordenar las subfilas de un campo de tipo anidado.

// 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 los resultados según la distancia desde un punto 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 paginación

Para paginar los resultados de una consulta, puede utilizar los parámetros limit y offset, o bien un token.

Paginación basada en desplazamiento

Puede utilizar la paginación basada en desplazamiento cuando el número total de filas a recuperar sea menor a 100,000. La suma de limit y offset debe ser menor o igual a 100,000, y el valor máximo para limit es 100.

Nota

Para aumentar el umbral de limit, consulte How do I increase the limit for the Search API to 1,000?.

Si no establece los parámetros limit y offset, limit tendrá un valor predeterminado de 10 y offset de 0.

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

Paginación basada en token

Se recomienda la paginación basada en token para la paginación profunda porque no tiene límite de profundidad.

Si una respuesta no contiene todos los datos coincidentes, el servidor devuelve un nextToken.

De forma predeterminada, la paginación basada en token solo permite avanzar a través de los resultados. Sin embargo, dado que un token permanece válido durante todo el proceso de consulta, puede almacenar en caché un token anterior para retroceder.

Importante

Si necesita conservar un nextToken o enviarlo a una aplicación front-end, utilice Base64 para codificarlo en una cadena. Un token es una matriz de bytes, no una cadena. Convertirlo directamente a una cadena con new String(nextToken) provoca pérdida de datos.

Cuando pagina con un token, el orden de clasificación es el mismo que en la solicitud anterior, ya sea que utilice el IndexSort predeterminado o una ordenación personalizada. Por lo tanto, no puede establecer un parámetro Sort cuando se usa un token. Tampoco puede establecer un offset, ya que solo puede leer datos secuencialmente.

Importante

Un índice de búsqueda que contiene un campo de tipo anidado no admite el preordenamiento del índice. Si necesita paginar resultados de dicho índice, debe especificar un orden de clasificación en la consulta. De lo contrario, el servidor no devolverá un nextToken incluso si hay más datos disponibles.

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