Combinar TOKENLISTs

Esta página descreve como concatenar TOKENLISTs em um índice de pesquisa ao configurar seu 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, é necessário que o aplicativo faça pesquisas 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. Tokenize palavras separadamente e concatenar os valores TOKENLIST resultantes (recomendado).
  2. Concatenar strings e tokenizar o resultado.

Com a segunda abordagem, há dois problemas:

  1. Se você quiser indexar Title ou Studio individualmente, além de indexá-los em um TOKENLIST combinado, o mesmo texto será tokenizado duas vezes. Isso faz com que as transações usem mais recursos.
  2. A 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 de TOKENLIST

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

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 no lado da consulta. Para mais informações, consulte Concatenação de TOKENLIST do 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 na mesma chamada TOKENLIST_CONCAT.

A definição de colunas TOKENLIST de texto pode ser alterada em colunas não armazenadas para adicionar outras colunas. Isso é útil quando você quer adicionar outra coluna a TOKENLIST_CONCAT. Mudar a expressão da coluna gerada não preenche as linhas atuais 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 TOKENLIST no lado da consulta

A desvantagem de indexar o TOKENLIST concatenado é que ele aumenta o custo de armazenamento e gravação. Cada token agora é armazenado no disco duas vezes: uma vez em uma lista de envio do TOKENLIST original e outra em uma lista de envio do TOKENLIST combinado. A 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 exemplo:

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 de gravação e da consulta produz 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 pode 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