Index de recherche numériques

En plus d'indexer du texte, l'index de recherche permet d'indexer efficacement des nombres. Il est principalement utilisé pour enrichir les requêtes de recherche en texte intégral avec des conditions sur les champs numériques. Cette page décrit l'indexation des nombres pour les requêtes d'égalité et d'inégalité, ainsi que l'indexation d'un tableau de nombres.

Tokeniser les nombres

Les tokeniseurs de nombres permettent de générer un ensemble de jetons utilisés pour accélérer les recherches de comparaison numérique.

Utilisez la fonction TOKENIZE_NUMBER pour créer un index numérique. TOKENIZE_NUMBER accepte INT64, FLOAT32, FLOAT64 ou ARRAY de ces types.

Pour PostgreSQL, utilisez la fonction spanner.tokenize_number pour créer un index numérique. spanner.tokenize_number n'est compatible qu'avec le type bigint.

Numéros d'index pour les requêtes d'égalité et d'inégalité

Spanner permet d'indexer des nombres pour l'égalité et l'inégalité. Les recherches d'égalité correspondent à un nombre. Les recherches par plage et par inégalité correspondent à un nombre compris dans une plage spécifique. Vous définissez cette valeur dans le paramètre TOKENIZE_NUMBER comparison_type :

  • Égalité : comparison_type=>"equality"
  • Inégalité et égalité : comparison_type=>"all"

Dans les deux cas, le nombre d'origine (entier ou à virgule flottante) est soumis à un processus de tokenisation, qui est conceptuellement similaire à la tokenisation de texte intégral. Il produit un ensemble de jetons que la requête peut ensuite utiliser pour localiser les documents correspondant à la condition numérique.

L'indexation d'égalité ne produit qu'un seul jeton, qui représente le nombre. Ce mode est recommandé si les requêtes ne comportent que des conditions sous la forme field = @p dans la clause WHERE.

L'indexation d'inégalité et d'égalité peut accélérer un plus grand nombre de conditions dans la clause WHERE de la requête. Cela inclut field < @p, field <= @p, field > @p, field >= @p, field BETWEEN @p1 and @p2 et field <> @p, en plus des conditions d'égalité. Pour implémenter ce type d'indexation, Spanner produit des jetons dans l'index de recherche sous-jacent. Spanner peut produire de nombreux jetons pour chaque nombre indexé, en fonction des paramètres de réglage. Le nombre de jetons dépend des paramètres définis pour TOKENIZE_NUMBER, tels que algorithm, min, max et granularity. Il est donc important d'évaluer soigneusement les paramètres de réglage pour assurer un équilibre approprié entre le stockage sur disque et le temps de recherche.

Pour les requêtes de plage sur des types d'entiers tels que INT64, spécifier algorithm => "prefixtree" peut améliorer considérablement les performances par rapport à l'algorithme logtree par défaut. Cet algorithme génère des jetons en fonction des préfixes numériques, ce qui permet un élagage plus efficace de l'espace de recherche pour les conditions de plage (par exemple, <= et >=). Pour les requêtes où la clause WHERE contient des prédicats de plage, l'algorithme prefixtree génère moins de jetons d'index pour les petits nombres par rapport à logtree, ce qui peut améliorer les performances et le coût de stockage.

Tokenisation de tableau

En plus des valeurs scalaires, TOKENIZE_NUMBER accepte la tokenisation d'un tableau de nombres (les exemples de cette section concernent les bases de données utilisant le dialecte GoogleSQL ; PostgreSQL n'est pas compatible avec l'accélération des tableaux numériques avec les index de recherche).

Lorsque TOKENIZE_NUMBER est utilisé avec la colonne ARRAY, vous devez spécifier comparison_type=>"equality". Les requêtes de plage ne sont pas compatibles avec un tableau de nombres.

  CREATE TABLE Albums (
    AlbumId STRING(MAX) NOT NULL,
    Ratings ARRAY<INT64>,
    Ratings_Tokens TOKENLIST
      AS (TOKENIZE_NUMBER(Ratings, comparison_type=>"equality")) HIDDEN
  ) PRIMARY KEY(AlbumId);

  CREATE SEARCH INDEX AlbumsIndex ON Albums(Ratings_Tokens);
  ```

The following query finds all albums that have a rating of 1 or 2:

 ```sql
  SELECT AlbumId
  FROM Albums
  WHERE ARRAY_INCLUDES_ANY(Ratings, [1, 2])
  ```

The following query finds all albums that were rated as 1 and as 5:

```sql
SELECT AlbumId
FROM Albums
WHERE ARRAY_INCLUDES_ALL(Ratings, [1, 5])
```

### Options for indexing high-precision numbers not supported by `TOKENIZE_NUMBER`

If you need to perform search queries on numeric types not directly supported by
`TOKENIZE_NUMBER` (such as `NUMERIC` or `BIGNUMERIC`),
consider these options:

*   **Schema Modification:** Change the column type to `INT64` for the subset of
    data that fits within the `INT64` range. Handle values exceeding the `INT64`
    range separately, potentially in a different table or using application
    logic.

*   **Conceptual Mapping to Supported Types:** Explore creating generated
    columns to map the `NUMERIC` values to an `INT64` range. This would allow
    `TOKENIZE_NUMBER` to be used on the generated column. Be sure to validate
    the query results against the original `NUMERIC` column in case your mapping
    does not perfectly preserve precision. The specifics of the mapping function
    needed for this approach are highly dependent on your specific data.

## What's next

*   Learn about [tokenization and Spanner
    tokenizers](/spanner/docs/full-text-search/tokenization).
*   Learn about [search indexes](/spanner/docs/full-text-search/search-indexes).
*   Learn about [index
    partitioning](/spanner/docs/full-text-search/partition-search-index).