Combiner des requêtes en texte intégral et non textuelles

Cette page explique comment effectuer une recherche combinant des données textuelles et non textuelles.

Les index de recherche sont compatibles avec les colonnes en texte intégral, en correspondance exacte et numériques. Vous pouvez combiner des conditions textuelles et non textuelles dans la clause WHERE, comme dans les requêtes de recherche multicolonne. L'optimiseur de requêtes tente d'optimiser les prédicats non textuels avec un indice de recherche. Si cela est impossible, Spanner évalue la condition pour chaque ligne correspondant à l'index de recherche. Les colonnes référencées qui ne sont pas stockées dans l'index de recherche sont extraites de la table de base.

Prenons l'exemple suivant:

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Title STRING(MAX),
  Rating FLOAT64,
  Genres ARRAY<STRING(MAX)>,
  Likes INT64,
  Cover BYTES(MAX),
  Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
  Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN,
  Genres_Tokens TOKENLIST AS (TOKEN(Genres)) HIDDEN
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex
ON Albums(Title_Tokens, Rating_Tokens, Genres_Tokens)
STORING Likes;

Le comportement des requêtes sur cette table est le suivant:

  • Rating et Genres sont inclus dans l'index de recherche. Spanner accélère les conditions à l'aide de listes d'affichage d'index de recherche.

    SELECT Album
    FROM Albums
    WHERE Rating > 4
      AND ARRAY_INCLUDES_ANY(Genres, ['jazz'])
    
  • La requête peut combiner des conjonctions, des disjonctions et des négations de quelque manière que ce soit, y compris en mélangeant des prédicats de texte complet et non textuels. Cette requête est entièrement accélérée par l'index de recherche.

    SELECT Album
    FROM Albums
    WHERE (SEARCH(Title_Tokens, 'car')
           OR Rating > 4)
      AND NOT ARRAY_INCLUDES_ANY(Genres, ['jazz'])
    
  • Likes est stocké dans l'index, mais le schéma ne demande pas à Spanner de créer un index de jetons pour ses valeurs possibles. Par conséquent, le prédicat de texte complet sur Title et le prédicat non textuel sur Rating sont accélérés, mais le prédicat sur Likes ne l'est pas. Dans Spanner, la requête extrait tous les documents contenant le terme "voiture" dans Title et ayant une note supérieure à 4, puis filtre les documents qui n'ont pas au moins 1 000 "J'aime". Cette requête utilise beaucoup de ressources si presque tous les albums contiennent le terme "voiture" dans leur titre et presque tous ont une note de 5, mais que peu d'albums ont 1 000 j'aime. Dans ce cas, l'indexation de Likes de la même manière que Rating permet d'économiser des ressources.

    SELECT Album
    FROM Albums
    WHERE SEARCH(Title_Tokens, 'car')
      AND Rating > 4
      AND Likes >= 1000
    
  • Cover n'est pas stocké dans l'index. La requête suivante effectue une jointure arrière entre AlbumsIndex et Albums pour extraire Cover pour tous les albums correspondants.

    SELECT AlbumId, Cover
    FROM Albums
    WHERE SEARCH(Title_Tokens, 'car')
      AND Rating > 4
    

Étape suivante