Al consultar un índice de búsqueda con el Tablestore SDK for Java, utilice la ordenación de índice o la ordenación en tiempo de consulta para controlar el orden de los resultados. Asimismo, emplee un desplazamiento (offset) o un token para paginar los resultados.
Requisitos previos
Instale Tablestore SDK for Java e inicialice un cliente.
Funcionamiento
Los índices de búsqueda admiten los siguientes mecanismos de ordenación:
Ordenación de índice: al crear un índice de búsqueda, configure
IndexSchema.indexSortpara definir el orden predeterminado de los resultados. Si no se configura la ordenación de índice, los resultados se ordenan por clave primaria. La ordenación de índice solo admitePrimaryKeySortyFieldSort. Un índice de búsqueda que contiene un campo Nested no es compatible con la ordenación de índice.Ordenación en tiempo de consulta: configure
SearchQuery.sortpara una consulta individual. Los resultados pueden ordenarse por puntuación de relevancia, clave primaria, valor de campo o distancia geográfica. Es posible combinar varios ordenadores para lograr una ordenación multinivel. A excepción de los campos de clave primaria, cualquier campo de ordenación debe tenerenableSortAndAggestablecido entruedentro del esquema del índice de búsqueda.
Cuando se especifica un ordenador en tiempo de consulta distinto al de clave primaria, el servidor añade automáticamente un ordenador de clave primaria para garantizar que las filas con el mismo valor de ordenación mantengan un orden determinista. Para deshabilitar este comportamiento, establezca Sort.disableDefaultPkSorter en true.
Utilice uno de los siguientes métodos de paginación para conjuntos de resultados grandes:
|
Método |
Caso de uso |
Características |
|
limit y offset |
El conjunto de resultados no supera las 100,000 filas y se requiere acceder a una posición específica. |
Admite saltos de página. La suma de |
|
token |
Paginación profunda o lectura secuencial de todos los resultados. |
No tiene el límite de profundidad de 100,000 filas, pero los resultados solo pueden leerse en secuencia. |
Llame al método search para consultar datos.
SearchResponse search(SearchRequest request)
El siguiente ejemplo devuelve las primeras 10 filas ordenadas por el campo score en orden descendente y, posteriormente, por clave primaria en orden ascendente.
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setLimit(10);
searchQuery.setSort(new Sort(Arrays.<Sort.Sorter>asList(
new FieldSort("score", SortOrder.DESC),
new PrimaryKeySort(SortOrder.ASC))));
SearchRequest request =
new SearchRequest("example_table", "example_index", searchQuery);
SearchResponse response = client.search(request);
Parámetros
Solicitud de consulta
El tipo de request es SearchRequest. La siguiente tabla describe sus parámetros.
|
Nombre |
Tipo |
Descripción |
|
tableName (obligatorio) |
String |
Nombre de la tabla de datos. |
|
indexName (obligatorio) |
String |
Nombre del índice de búsqueda. |
|
searchQuery (obligatorio) |
SearchQuery |
Condición de consulta, junto con las configuraciones de ordenación y paginación. |
|
columnsToGet (opcional) |
SearchRequest.ColumnsToGet |
Columnas que se devolverán. Si no se configura este parámetro, solo se devuelven las columnas de clave primaria. |
Configuración de consulta
El tipo de request.searchQuery es SearchQuery. La siguiente tabla describe únicamente los parámetros relacionados con la ordenación y la paginación.
|
Nombre |
Tipo |
Descripción |
|
query (obligatorio) |
Query |
Condición de la consulta. |
|
sort (opcional) |
Sort |
Configuración de ordenación en tiempo de consulta. Si no se configura este parámetro, se utiliza la ordenación de índice. No configure este parámetro para la paginación basada en tokens. Después de llamar a |
|
offset (opcional) |
Integer |
Posición desde la cual comienza la consulta actual. Valor predeterminado: |
|
limit (opcional) |
Integer |
Número máximo de filas a devolver. Valor predeterminado: |
|
token (opcional) |
byte[] |
Token de paginación. Establezca este parámetro con el valor |
|
trackTotalCount (opcional) |
int |
Número máximo esperado de filas coincidentes a contar. Valor predeterminado: |
Configuración de ordenación
El tipo de request.searchQuery.sort es Sort. La siguiente tabla describe sus parámetros.
|
Nombre |
Tipo |
Descripción |
|
sorters (obligatorio) |
|
Lista de ordenadores. El orden de la lista determina la prioridad de la ordenación multinivel. Los ordenadores compatibles son |
|
disableDefaultPkSorter (opcional) |
Boolean |
Especifica si se debe evitar que el servidor añada automáticamente un ordenador de clave primaria. Valor predeterminado: |
Ordenación por puntuación de relevancia
ScoreSort ordena las filas según la puntuación de relevancia calculada mediante el algoritmo BM25. La siguiente tabla describe su parámetro.
|
Nombre |
Tipo |
Descripción |
|
order (opcional) |
SortOrder |
Orden de clasificación. |
Para ordenar por puntuación de relevancia, configure explícitamente ScoreSort. De lo contrario, se utilizará la ordenación de índice.
Ordenación por clave primaria
PrimaryKeySort ordena las filas por clave primaria. La siguiente tabla describe su parámetro.
|
Nombre |
Tipo |
Descripción |
|
order (opcional) |
SortOrder |
Orden de clasificación. Valor predeterminado: |
Ordenación por campo
FieldSort ordena las filas por valor de campo. La siguiente tabla describe sus parámetros.
|
Nombre |
Tipo |
Descripción |
|
fieldName (obligatorio) |
String |
Nombre del campo de ordenación. La ordenación y la agregación deben estar habilitadas para dicho campo. |
|
order (opcional) |
SortOrder |
Orden de clasificación. Valor predeterminado: |
|
mode (opcional) |
SortMode |
Valor que se utiliza al ordenar un campo con múltiples valores. |
|
missingFields (opcional) |
|
Lista de campos de ordenación alternativos. Si falta el campo de ordenación actual, se utiliza el primer campo de la lista que tenga un valor. Un campo alternativo debe ser del mismo tipo que el campo de ordenación. |
|
missingValue (opcional) |
ColumnValue |
Valor de ordenación que se utiliza si faltan tanto el campo de ordenación como todos los campos alternativos. Establezca este parámetro en |
|
nestedFilter (opcional) |
NestedFilter |
Configuración de ordenación Nested que especifica la ruta Nested y las filas secundarias que participan en la ordenación. Configure este parámetro solo al ordenar un subcampo Nested. |
Filtro Nested
El tipo de FieldSort.nestedFilter es NestedFilter. La siguiente tabla describe sus parámetros.
|
Nombre |
Tipo |
Descripción |
|
path (obligatorio) |
String |
Ruta del campo Nested. |
|
query (obligatorio) |
Query |
Condición de consulta que selecciona las filas secundarias Nested que participan en la ordenación. Establezca el parámetro en |
Ordenación por distancia geográfica
GeoDistanceSort ordena las filas según la distancia entre un campo de punto geográfico y los puntos objetivo. La siguiente tabla describe sus parámetros.
|
Nombre |
Tipo |
Descripción |
|
fieldName (obligatorio) |
String |
Nombre del campo Geopoint. |
|
points (obligatorio) |
|
Puntos geográficos objetivo. Cada punto utiliza el formato |
|
order (opcional) |
SortOrder |
Orden de clasificación. |
|
mode (opcional) |
SortMode |
Valor que se utiliza cuando existen múltiples distancias. Los valores compatibles son |
|
distanceType (opcional) |
GeoDistanceType |
Método de cálculo de distancia. |
|
nestedFilter (opcional) |
NestedFilter |
Configuración de ordenación Nested. Configure este parámetro solo al ordenar un subcampo Nested. |
Columnas a devolver
El tipo de request.columnsToGet es SearchRequest.ColumnsToGet. El hecho de que las columnas devueltas deban leerse desde la tabla de datos afecta el valor límite máximo.
|
Nombre |
Tipo |
Descripción |
|
columns (opcional) |
|
Nombres de las columnas de atributos a devolver. Los datos pueden leerse directamente del índice de búsqueda solo si todas las columnas de atributos especificadas están indexadas y tienen habilitado el almacenamiento. |
|
returnAll (opcional) |
boolean |
Especifica si se deben devolver todas las columnas de atributos de la tabla de datos. Valor predeterminado: |
|
returnAllFromIndex (opcional) |
boolean |
Especifica si se deben devolver todas las columnas de atributos almacenadas en el índice de búsqueda. Valor predeterminado: |
Respuesta
El método search devuelve SearchResponse. La siguiente tabla describe los campos relacionados con la ordenación y la paginación.
|
Nombre |
Tipo |
Descripción |
|
rows |
|
Filas devueltas por la consulta actual. Llame a |
|
searchHits |
|
Coincidencias de la búsqueda. Llame a |
|
totalCount |
long |
Número de filas coincidentes. Llame a |
|
nextToken |
byte[] |
Token para la siguiente página. Llame a |
|
isAllSuccess |
boolean |
Indica si se consultaron todas las particiones del índice. Llame a |
Ejemplos
Configurar la ordenación de índice
El siguiente ejemplo configura el campo score como campo de ordenación de índice al crear un índice de búsqueda. Si no se configura la ordenación para una consulta, los resultados se devuelven en orden ascendente de score.
FieldSchema score = new FieldSchema("score", FieldType.LONG)
.setEnableSortAndAgg(true);
IndexSchema indexSchema = new IndexSchema();
indexSchema.setFieldSchemas(Collections.singletonList(score));
indexSchema.setIndexSort(new Sort(
Collections.<Sort.Sorter>singletonList(
new FieldSort("score", SortOrder.ASC))));
Ordenar por puntuación de relevancia
El siguiente ejemplo devuelve resultados en orden descendente según la puntuación de relevancia BM25.
TermQuery termQuery = new TermQuery();
termQuery.setFieldName("category");
termQuery.setTerm(ColumnValue.fromString("book"));
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(termQuery);
searchQuery.setSort(new Sort(
Collections.<Sort.Sorter>singletonList(new ScoreSort())));
Gestionar valores de campo faltantes
El siguiente ejemplo ordena las filas por el campo score en orden descendente. Si una fila no contiene el campo, se utiliza el valor de score_backup. Si ambos campos faltan, la fila se coloca al final.
FieldSort fieldSort = new FieldSort("score", SortOrder.DESC);
fieldSort.setMissingFields(Collections.singletonList("score_backup"));
fieldSort.setMissingValue(FieldSort.LAST_WHEN_MISSING);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setSort(new Sort(
Collections.<Sort.Sorter>singletonList(fieldSort)));
Ordenar campos con múltiples valores y campos Nested
Al ordenar un arreglo u otro campo con múltiples valores, utilice mode para especificar el valor que participa en la ordenación. El siguiente ejemplo ordena las filas en orden descendente según el valor máximo en el arreglo scores.
FieldSort fieldSort = new FieldSort("scores", SortOrder.DESC);
fieldSort.setMode(SortMode.MAX);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setSort(new Sort(
Collections.<Sort.Sorter>singletonList(fieldSort)));
Al ordenar un subcampo Nested, configure también la ruta Nested y seleccione las filas secundarias que participarán en la ordenación. El siguiente ejemplo utiliza únicamente las filas secundarias donde items.age es 1 y ordena las filas en orden ascendente según el valor mínimo de items.name.
TermQuery ageQuery = new TermQuery();
ageQuery.setFieldName("items.age");
ageQuery.setTerm(ColumnValue.fromLong(1));
FieldSort fieldSort = new FieldSort("items.name", SortOrder.ASC);
fieldSort.setMode(SortMode.MIN);
fieldSort.setNestedFilter(new NestedFilter("items", ageQuery));
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setSort(new Sort(
Collections.<Sort.Sorter>singletonList(fieldSort)));
Ordenar por distancia geográfica
El siguiente ejemplo devuelve filas del punto más cercano al más lejano basándose en la distancia esférica entre el campo location y 30.23,120.19.
GeoDistanceSort geoSort = new GeoDistanceSort(
"location", Collections.singletonList("30.23,120.19"));
geoSort.setOrder(SortOrder.ASC);
geoSort.setDistanceType(GeoDistanceType.ARC);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setSort(new Sort(
Collections.<Sort.Sorter>singletonList(geoSort)));
Paginar mediante limit y offset
El siguiente ejemplo omite las primeras 100 filas y devuelve las siguientes 100. Al utilizar este método, la suma de limit y offset no puede exceder 100,000.
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setLimit(100);
searchQuery.setOffset(100);
Paginar mediante un token
El siguiente ejemplo lee todos los resultados en un bucle. El token es null para la primera consulta. Cada consulta subsiguiente utiliza directamente el nextToken de la respuesta anterior. Después de llamar a setToken, el SDK borra la ordenación porque el token contiene las condiciones de ordenación de la página anterior.
List<Row> rows = new ArrayList<Row>();
byte[] nextToken = null;
do {
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
searchQuery.setLimit(100);
searchQuery.setToken(nextToken);
SearchRequest request =
new SearchRequest("example_table", "example_index", searchQuery);
SearchResponse response = client.search(request);
rows.addAll(response.getRows());
nextToken = response.getNextToken();
} while (nextToken != null);
No es posible configurar el desplazamiento (offset) ni saltar páginas durante la paginación basada en tokens. Para volver a una página anterior, almacene en caché el token utilizado para solicitar cada página y emita otra consulta utilizando el token correspondiente a la página deseada.
Un índice de búsqueda que contiene un campo Nested carece de ordenación de índice. Para usar la paginación basada en tokens con este tipo de índice, configure explícitamente la ordenación en la primera consulta. De lo contrario, el servidor no devolverá nextToken.
Para consultas secuenciales dentro del mismo proceso, pase nextToken directamente como un arreglo de bytes. Utilice la codificación Base64 únicamente cuando el token deba persistirse o transferirse entre procesos, o entre un frontend y un backend. No convierta el token mediante new String(nextToken), ya que esto corrompe el token.
String encodedToken = Base64.getEncoder().encodeToString(nextToken);
byte[] decodedToken = Base64.getDecoder().decode(encodedToken);