Combinar TOKENLISTs

Esta página descreve como concatenar TOKENLISTs em uma índice de pesquisa ao configurar o esquema ou em uma consulta de pesquisa ao realizar uma pesquisa de texto completo no Spanner.

Combinar TOKENLISTs em um índice de pesquisa

Às vezes, você precisa que o aplicativo pesquise em campos individuais. Em outros momentos, o aplicativo precisa pesquisar em todos os campos. Por exemplo, em uma tabela com duas colunas de string, talvez você queira que o app pesquise nas duas colunas sem diferenciar de qual coluna as correspondências vêm.

No Spanner, há duas maneiras de fazer isso:

  1. Tokenizar palavras separadamente e concatenar os valores TOKENLIST resultantes (recomendado).
  2. Concatene strings e tokenize o resultado.

Com a segunda abordagem, há dois problemas:

  1. Se você quiser indexar Title ou Studio individualmente, além de indexá-los em uma TOKENLIST combinada, o mesmo texto será tokenizado duas vezes. Isso faz com que as transações usem mais recursos.
  2. Uma pesquisa de frase abrange os dois campos. Por exemplo, se @p for definido como "Blue Note", ele vai corresponder a uma linha que contém Title="Big Blue Note" e Studio="Blue Note Studios".

A primeira abordagem resolve esses problemas porque uma frase corresponde apenas a um campo, e cada campo de string é tokenizado apenas uma vez se o TOKENLIST individual e combinado forem indexados. Embora cada campo de string seja tokenizado apenas uma vez, as TOKENLISTs resultantes são armazenadas separadamente no índice.

Tokenizar palavras separadamente e concatenar valores TOKENLIST

O exemplo a seguir tokeniza cada palavra e concatena o TOKENLIST valores:

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,
  Combined_Tokens TOKENLIST AS (TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens])) HIDDEN,
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Combined_Tokens);

SELECT AlbumId FROM Albums WHERE SEARCH(Combined_Tokens, @p);

A concatenação TOKENLIST também pode ser implementada totalmente na consulta. Para mais informações, consulte Concatenação de TOKENLIST no lado da consulta.

TOKENLIST_CONCAT é compatível com pesquisas de texto completo e substring. O Spanner não permite misturar tipos de tokenização, como TOKENIZE_FULLTEXT e TOKENIZE_SUBSTRING no mesmo TOKENLIST_CONCAT a chamada.

A definição de colunas TOKENLIST de texto pode ser alterada em colunas não armazenadas para adicionar outras colunas. Isso é útil quando você deseja adicionar um para TOKENLIST_CONCAT. Alterar a expressão de coluna gerada preencherá as linhas existentes no índice.

Concatenar strings e tokenizar o resultado

O exemplo a seguir concatena strings e tokeniza o resultado:

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

CREATE SEARCH INDEX AlbumsIndex ON Albums(Combined_Tokens);

SELECT AlbumId FROM Albums WHERE SEARCH(Combined_Tokens, @p);

Concatenação de TOKENLIST do lado da consulta

A desvantagem de indexar o TOKENLIST concatenado é que ela aumenta armazenamento e gravação. Agora, cada token é armazenado duas vezes no disco: uma vez em uma lista de postagens de sua TOKENLIST original e outra em uma lista de postagens dos TOKENLIST combinados. Concatenação do lado da consulta de colunas TOKENLIST evita esse custo, mas a consulta usa mais recursos de computação.

Para concatenar vários TOKENLISTs, use a função TOKENLIST_CONCAT na consulta SEARCH. Nesta seção, usamos o seguinte esquema de amostra:

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);

A consulta a seguir pesquisa linhas que têm os tokens "blue" e "note" em qualquer lugar nas colunas Title e Studio. Isso inclui linhas com "blue" e "note" na coluna Title, "blue" e "note" na coluna Studio e "blue" na coluna Title e "note" na coluna Studio, ou o oposto.

SELECT AlbumId
FROM Albums
WHERE SEARCH(TOKENLIST_CONCAT([AlbumTitle_Tokens, Studio_Tokens]), 'blue note')

A concatenação TOKENLIST do lado da gravação e do lado da consulta produzem resultados idênticos. A escolha entre os dois é um trade-off entre o custo do disco e o custo da consulta.

Como alternativa, um aplicativo poderia pesquisar várias colunas TOKENLIST e usar OR com a função SEARCH:

SEARCH(AlbumTitle_Tokens, 'Blue Note') OR SEARCH(Studio_Tokens, 'Blue Note')

No entanto, isso tem semântica diferente. Não corresponde a álbuns em que AlbumTitle_Tokens tem "blue", mas não "note", e Studio_Tokens tem "note", mas não "blue".

A seguir