Pesquisar várias colunas em índices de pesquisa

Os índices de pesquisa podem indexar várias colunas tokenizadas, tornando as consultas nessas colunas mais eficientes. Esta página descreve como realizar uma pesquisa em várias colunas, que é um tipo de pesquisa de texto completo.

A estrutura do índice de pesquisa garante que as consultas não precisem de uma união distribuída, garantindo a performance previsível das consultas. A união distribuída é evitada devido à colocação de todos os tokens que correspondem a uma linha da tabela base na mesma divisão.

Por exemplo, considere o esquema a seguir:

GoogleSQL

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Title STRING(MAX),
  Studio STRING(MAX),
  Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
  Studio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Studio)) HIDDEN
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Title_Tokens, Studio_Tokens);

PostgreSQL

CREATE TABLE albums (
  albumid character varying NOT NULL,
  title character varying,
  studio character varying,
  title_tokens spanner.tokenlist
      GENERATED ALWAYS AS (TOKENIZE_FULLTEXT(title)) VIRTUAL HIDDEN,
  studio_tokens spanner.tokenlist
      GENERATED ALWAYS AS (TOKENIZE_FULLTEXT(studio)) VIRTUAL HIDDEN,
) PRIMARY KEY(albumid);

CREATE SEARCH INDEX albumsindex ON albums(title_tokens, studio_tokens);

Uma consulta agora pode pesquisar dois campos: Title_Tokens e Studio_Tokens.

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, "fifth symphony")
  AND SEARCH(Studio_Tokens, "Blue Note Studio")

PostgreSQL

SELECT albumid
FROM albums
WHERE spanner.search(title_tokens, 'fifth symphony')
  AND spanner.search(studio_tokens, 'Blue Note Studio')

O Spanner oferece suporte a consultas de pesquisa em várias colunas em conjunto, disjunção e operadores de negação na cláusula WHERE. É possível usar todos os tipos de consultas a seguir com um índice de pesquisa:

  • Conjunção: encontrar documentos em que Title tenha o termo "car" e Studio tenha o termo "sun".

    GoogleSQL

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(Title_Tokens, 'car') AND SEARCH(Studio_Tokens, 'sun')
    

    PostgreSQL

    SELECT albumid
    FROM albums
    WHERE spanner.search(title_tokens, 'car') AND spanner.search(studio_tokens, 'sun')
    
  • Disjunção: encontrar documentos em que Title tenha o termo "car" ou Studio tenha o termo "sun".

    GoogleSQL

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(Title_Tokens, 'car') OR SEARCH(Studio_Tokens, 'sun')
    

    PostgreSQL

    SELECT albumid
    FROM albums
    WHERE spanner.search(title_tokens, 'car') OR spanner.search(studio_tokens, 'sun')
    
  • Negação: encontrar todos os documentos em que Title não contenha o termo "car".

    GoogleSQL

    SELECT AlbumId
    FROM Albums
    WHERE NOT SEARCH(Title_Tokens, 'car')
    

    PostgreSQL

    SELECT albumid
    FROM albums
    WHERE NOT spanner.search(title_tokens, 'car')
    

    A linguagem rquery pode realizar o mesmo tipo de pesquisa:

    GoogleSQL

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(Title_Tokens, '-car')
    

    PostgreSQL

    SELECT albumid
    FROM albums
    WHERE spanner.search(title_tokens, '-car')
    

    Ambas as formas filtram documentos em que Title é NULL. As funções de tokenização e pesquisa são definidas para retornar NULL na entrada NULL. O SQL define NOT NULL como NULL.

Além disso, é possível referenciar a mesma coluna TOKENLIST várias vezes.

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE (SEARCH(Title_Tokens, 'car') OR SEARCH(Studio_Tokens, 'sun'))
  AND (SEARCH(Title_Tokens, 'guy') OR SEARCH(Studio_Tokens, electric))

PostgreSQL

SELECT albumid
FROM albums
WHERE (spanner.search(title_tokens, 'car') OR spanner.search(studio_tokens, 'sun'))
  AND (spanner.search(title_tokens, 'guy') OR spanner.search(studio_tokens, 'electric'))

Use a linguagem rquery ou o SQL para pesquisar vários termos na mesma coluna. O rquery é recomendado devido ao armazenamento em cache eficiente de consultas parametrizadas. Além da melhor taxa de ocorrência em cache de consultas, as linguagens rquery e SQL têm as mesmas taxas de latência e performance.

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, 'car OR guy')

SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, 'car') OR SEARCH(Title_Tokens, 'guy')

PostgreSQL

SELECT albumid
FROM albums
WHERE spanner.search(title_tokens, 'car OR guy')

SELECT albumid
FROM albums
WHERE spanner.search(title_tokens, 'car') OR spanner.search(title_tokens, 'guy')

Também é possível usar condições não textuais aceleradas com índices de pesquisa na mesma consulta com funções de pesquisa de texto completo.

A seguir