Esta página descreve como concatenar TOKENLIST
s 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:
- Tokenize palavras separadamente e concatenar os
TOKENLIST
s resultantes (recomendado). - Concatenar strings e tokenizar o resultado.
Com a segunda abordagem, há dois problemas:
- Se você quiser indexar
Title
ouStudio
individualmente, além de indexá-los em umTOKENLIST
combinado, o mesmo texto será tokenizado duas vezes. Isso faz com que as transações usem mais recursos. - 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émTitle
="Big Blue Note" eStudio
="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 os TOKENLIST
s individuais e combinados
forem indexados. Embora cada campo de string seja tokenizado apenas uma vez,
os TOKENLIST
s resultantes são armazenados separadamente no índice.
Tokenizar palavras separadamente e concatenar TOKENLIST
s
O exemplo a seguir tokeniza cada palavra e usa
TOKENLIST_CONCAT
para concatenar os TOKENLIST
s:
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,
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);
PostgreSQL
O PostgreSQL usa
spanner.tokenlist_concat
para concatenação. O parâmetro de consulta $1
está vinculado a "Hatel Kaliphorn".
CREATE TABLE albums (
albumid character varying NOT NULL,
title character varying,
studio character varying,
title_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(title)) VIRTUAL HIDDEN,
studio_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(studio)) VIRTUAL HIDDEN,
combined_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenlist_concat(ARRAY[spanner.tokenize_fulltext(title), spanner.tokenize_fulltext(studio)])) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));
CREATE SEARCH INDEX albumsindex ON albums(combined_tokens);
SELECT albumid FROM albums WHERE spanner.search(combined_tokens, $1);
tokenlist_concat
não chama title_tokens
ou studio_tokens
,
mas chama spanner.tokenize_fulltext(title)
e
spanner.tokenize_fulltext(studio)
. Isso ocorre porque o PostgreSQL
não oferece suporte à referência de colunas geradas que estão em outras colunas
geradas. O spanner.tokenlist_concat
precisa chamar funções de tokenização e não
referenciar colunas de lista de tokens diretamente.
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.
O 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
.
No GoogleSQL, a definição de colunas de texto TOKENLIST
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:
GoogleSQL
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);
PostgreSQL
CREATE TABLE albums (
albumid character varying NOT NULL,
title character varying,
studio character varying,
combined_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(title || ' ' || studio)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));
CREATE SEARCH INDEX albumsindex ON albums(combined_tokens);
SELECT albumid FROM albums WHERE spanner.search(combined_tokens, $1);
Concatenação de 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 TOKENLIST
s, use a função
TOKENLIST_CONCAT
na consulta
SEARCH
. Nesta seção, usamos o seguinte esquema de exemplo:
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 (spanner.tokenize_fulltext(title)) VIRTUAL HIDDEN,
studio_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(studio)) VIRTUAL 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.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(TOKENLIST_CONCAT([AlbumTitle_Tokens, Studio_Tokens]), 'blue note')
PostgreSQL
Este exemplo usa
spanner.search
com
spanner.tokenlist_concat
.
SELECT albumid
FROM albums
WHERE spanner.search(spanner.tokenlist_concat(ARRAY[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
:
GoogleSQL
SEARCH(AlbumTitle_Tokens, 'Blue Note') OR SEARCH(Studio_Tokens, 'Blue Note')
PostgreSQL
spanner.search(albumtitle_tokens, 'Blue Note') OR spanner.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
- Saiba mais sobre consultas de pesquisa de texto completo.
- Saiba mais sobre índices de pesquisa.