Outre les types primitifs tels que Long, Double, Boolean, Keyword, Text, Date, GeoPoint, Vector, IP et JSON, les index de recherche prennent en charge les types de données Array et Nested. Utilisez le type Array pour stocker plusieurs valeurs du même type et le type Nested pour stocker des données hiérarchiques similaires au format JSON.
Type de données Array
Le type de données Array s'applique uniquement aux index de recherche. Les tables de données ne le prennent pas en charge.
Interrogez un champ Array comme n'importe quel autre champ. Une ligne est renvoyée si au moins une valeur du tableau satisfait la condition de requête.
Le type de données Vector ne prend pas en charge les tableaux.
Le type Array est un modificateur qui se combine avec des types primitifs tels que Long, Double, Boolean, Keyword, Text, Date, IP et GeoPoint. Par exemple, l'association du type Array au type Long crée un tableau d'entiers longs capable de stocker plusieurs valeurs de ce type.
Formats Array
Le tableau suivant décrit les formats de tableau pour les types de données primitifs dans les index de recherche.
|
Type Array |
Description |
|
Long Array |
Tableau d'entiers longs. Exemple : |
|
Double Array |
Tableau de nombres à virgule flottante. Exemple : |
|
Boolean Array |
Tableau de valeurs booléennes. Exemple : |
|
Keyword Array |
Tableau de chaînes au format JSON. Exemple : |
|
Text Array |
Tableau de texte au format JSON. Exemple : L'utilisation des tableaux de texte est rare. |
|
Date Array |
Tableau de dates. Si le type de date est un entier, le format est |
|
IP Array |
Tableau d'adresses IP au format JSON. Exemple : |
|
Geopoint Array |
Tableau de points géographiques. Exemple : |
Notes d'utilisation
Pour les champs de type Array dans un index de recherche, le champ correspondant dans la table de données doit être de type String, tandis que le champ dans l'index de recherche doit être du type primitif correspondant, tel que Long ou Double.
Par exemple, si le champ price est de type Double Array, le champ price dans la table de données doit être de type String. Dans l'index de recherche, définissez le type de champ sur Double et ajoutez la propriété isArray=true.
Exemples
Supposons qu'une table de données nommée array_search_table contient les exemples de données suivants.
La table de données comprend la colonne de clé primairepk(de type String) et deux colonnes d'attribut :col_keyword_array(de type String) etcol_long_array(de type String).
|
pk |
col_keyword_array |
col_long_array |
|
03#server#07 |
["Development environment", "Test environment", "Physical server", "Linux" ] |
[2020, 2023] |
|
4c#server#ae |
["Production environment", "Cloud server", "Linux" ] |
[2021, 2024] |
-
Créez un index de recherche.
Créez un index de recherche nommé
array_query_table_index. L'index inclut deux colonnes :col_keyword_array(de type String Array) etcol_long_array(de type Long Array).Pour Schema Generation Method, sélectionnez Auto-generate. Ensuite, dans le tableau de configuration des champs, vérifiez que le commutateur Array est activé pour les champs correspondants.
-
Interrogez les données de type Array à l'aide de l'index de recherche.
Le code Java suivant interroge les données de tableau où la colonne
col_keyword_arraycontient un élément correspondant exactement à « Cloud server » et la colonnecol_long_arraycontient un élément égal à 2024.RemarquePour interroger des données de type Array dans un index de recherche à l'aide d'instructions SQL, consultez Execute SQL statements to query data using the search index.
private static void query(SyncClient client) { // Condition 1: The col_keyword_array field contains an element that is an exact match for "ECS". TermQuery keywordTermQuery = new TermQuery(); keywordTermQuery.setFieldName("col_keyword_array"); keywordTermQuery.setTerm(ColumnValue.fromString("ECS")); // Condition 2: The col_long_array field contains an element equal to 2024. TermQuery longTermQuery = new TermQuery(); longTermQuery.setFieldName("col_long_array"); longTermQuery.setTerm(ColumnValue.fromLong(2024l)); SearchQuery searchQuery = new SearchQuery(); // Require both conditions to be true. BoolQuery boolQuery = new BoolQuery(); boolQuery.setMustQueries(Arrays.asList(keywordTermQuery, longTermQuery)); searchQuery.setQuery(boolQuery); //searchQuery.setGetTotalCount(true); // Set to return the total number of matched rows. SearchRequest searchRequest = new SearchRequest("<TABLE_NAME>", "<SEARCH_INDEX_NAME>", searchQuery); // You can configure the columnsToGet parameter to specify the columns to return or return all columns. If this parameter is not configured, only primary key columns are returned by default. //SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet(); //columnsToGet.setReturnAll(true); // Set to return all columns. //columnsToGet.setColumns(Arrays.asList("ColName1","ColName2")); // Set to return specified columns. //searchRequest.setColumnsToGet(columnsToGet); SearchResponse resp = client.search(searchRequest); //System.out.println("TotalCount: " + resp.getTotalCount()); // Print the total number of matched rows, not the number of returned rows. System.out.println("Row: " + resp.getRows()); }
Type de données Nested
Le type Nested représente des documents imbriqués. Une ligne de données (document) peut contenir plusieurs lignes enfants (documents enfants) stockées dans un champ imbriqué. Ce type convient au stockage de données hiérarchiques.
Spécifiez le schéma des lignes enfants dans un champ imbriqué, y compris les champs et les propriétés de chaque ligne enfant. Le type Nested prend en charge plusieurs valeurs et est similaire au type de données JSON.
Formats Nested
Les champs imbriqués sont classés en types à un seul niveau et à plusieurs niveaux.
|
Type d'imbrication |
Description |
|
Type imbriqué à un seul niveau |
Contient une couche de structure de données imbriquée avec une hiérarchie de base. Convient aux scénarios nécessitant des relations parent-enfant simples sans plusieurs niveaux. Exemple :
|
|
Type imbriqué à plusieurs niveaux |
Contient plusieurs couches de structures de données imbriquées avec une hiérarchie complexe. Adapté aux modèles de données qui requièrent des hiérarchies riches et un degré élevé de modularité. Exemple :
|
Notes d'utilisation
Pour les champs de type Nested dans un index de recherche, le champ correspondant dans la table de données doit être de type String, tandis que le champ dans l'index de recherche doit être de type Nested. Utilisez des requêtes imbriquées pour interroger les champs de type Nested.
Lors de l'écriture des données dans la table de données, formatez la valeur du champ imbriqué sous forme de tableau JSON d'objets. Par exemple, [{"tagName":"tag1", "score":0.8,"time": 1730690237000 }, {"tagName":"tag2", "score":0.2,"time": 1730691557000}].
Écrivez toujours les données sous forme de chaîne de tableau JSON dans un champ imbriqué, même si le champ ne contient qu'une seule ligne enfant.
Exemples
Exemple de champs Nested à un seul niveau
Créez un champ Nested à un seul niveau dans la console Tablestore ou à l'aide d'un SDK Tablestore.
L'exemple de code Java suivant montre comment créer un champ imbriqué nommé tags. Les lignes enfants contiennent les trois champs suivants.
Nom du champ : tagName. Type de champ : Keyword.
Nom du champ : score. Type de champ : Double.
Nom du champ : time. Type de champ : Date. Unité : millisecondes.
Les exemples de données écrites dans la table de données sont [{"tagName":"tag1", "score":0.8,"time": 1730690237000 }, {"tagName":"tag2", "score":0.2,"time": 1730691557000}].
// Create FieldSchema objects for the fields in a child row.
List<FieldSchema> subFieldSchemas = new ArrayList<FieldSchema>();
subFieldSchemas.add(new FieldSchema("tagName", FieldType.KEYWORD)
.setIndex(true).setEnableSortAndAgg(true));
subFieldSchemas.add(new FieldSchema("score", FieldType.DOUBLE)
.setIndex(true).setEnableSortAndAgg(true));
subFieldSchemas.add(new FieldSchema("time", FieldType.DATE)
.setDateFormats(Arrays.asList("epoch_millis")));
// Set the child row FieldSchema objects to the subFieldSchemas of the nested field.
FieldSchema nestedFieldSchema = new FieldSchema("tags", FieldType.NESTED)
.setSubFieldSchemas(subFieldSchemas);
Exemple de champs Nested à plusieurs niveaux
Créez un champ Nested à plusieurs niveaux à l'aide d'un SDK Tablestore.
L'exemple suivant utilise le SDK Tablestore pour Java afin de créer un champ Nested nommé user. Chaque ligne enfant contient quatre champs de type primitif et un champ Nested.
Nom du champ : name. Type de champ : Keyword.
Nom du champ : age. Type de champ : Long.
Nom du champ : birth. Type de champ : Date. Format de valeur : chaîne de date.
Nom du champ : phone. Type de champ : Keyword.
Nom du champ imbriqué : address. Champs de la ligne enfant : province, city et street. Type de données : Keyword pour tous les champs.
Exemple de données à écrire dans la table de données : [ {"name":"Zhang San","age":20,"birth":"2014-10-10 12:00:00.000","phone":"1390000****","address":[{"province":"Zhejiang Province","city":"Hangzhou City","street":"No. 1201, Xingfu Community, Sunshine Avenue"}]}]
// Define subfield schemas for the 'address' nested field. The query path for these fields is user.address.
List<FieldSchema> addressSubFiledSchemas = new ArrayList<>();
addressSubFiledSchemas.add(new FieldSchema("province",FieldType.KEYWORD));
addressSubFiledSchemas.add(new FieldSchema("city",FieldType.KEYWORD));
addressSubFiledSchemas.add(new FieldSchema("street",FieldType.KEYWORD));
// Define subfield schemas for the 'user' nested field. Each child row contains four primitive type fields and one nested field 'address'.
List<FieldSchema> subFieldSchemas = new ArrayList<>();
subFieldSchemas.add(new FieldSchema("name",FieldType.KEYWORD));
subFieldSchemas.add(new FieldSchema("age",FieldType.LONG));
subFieldSchemas.add(new FieldSchema("birth",FieldType.DATE).setDateFormats(Arrays.asList("yyyy-MM-dd HH:mm:ss.SSS")));
subFieldSchemas.add(new FieldSchema("phone",FieldType.KEYWORD));
subFieldSchemas.add(new FieldSchema("address",FieldType.NESTED).setSubFieldSchemas(addressSubFiledSchemas));
// Add the 'user' nested field schema to the list of main field schemas.
List<FieldSchema> fieldSchemas = new ArrayList<>();
fieldSchemas.add(new FieldSchema("user",FieldType.NESTED).setSubFieldSchemas(subFieldSchemas));
Limites
Les index de recherche contenant des champs Nested ne prennent pas en charge IndexSort, une fonctionnalité qui améliore les performances des requêtes dans divers scénarios.
Lors de la pagination des résultats de requête provenant d'un index de recherche contenant des champs Nested, spécifiez une méthode de tri dans les conditions de requête. Sinon, Tablestore ne renvoie pas nextToken lorsque seuls des résultats partiels sont lus.
Les requêtes imbriquées offrent des performances inférieures à celles des autres types de requêtes.
En dehors de ces limites, le type Nested prend en charge tous les types de requêtes, le tri et l'agrégation.
Références
Search Index prend en charge divers types de requêtes pour les interrogations de données multidimensionnelles, notamment term query, terms query, match all query, match query, phrase match query, range query, prefix query, suffix query, wildcard query, token-based wildcard query, boolean query, geo query, nested query, vector search, et exists query.
Lorsque vous interrogez des données, vous pouvez sort and paginate l'ensemble de résultats ou effectuer un collapsing (deduplication).
Pour l'analyse des données, telle que la recherche de la valeur maximale ou minimale, le calcul d'une somme ou le comptage de lignes, vous pouvez utiliser les fonctionnalités statistical aggregation ou SQL query.
Pour exporter rapidement des données indépendamment de l'ordre de l'ensemble de résultats, vous pouvez utiliser la fonctionnalité Parallel Scan.