Questa pagina descrive come concatenare i valori TOKENLIST
in un
indice di ricerca quando configuri lo schema o in una query di ricerca quando esegui una ricerca a testo intero in Spanner.
Combinare gli elenchi TOKENLIST in un indice di ricerca
A volte, è necessario che l'applicazione esegua ricerche in singoli campi. Altre volte, l'applicazione deve eseguire ricerche in tutti i campi. Ad esempio, in una tabella con due colonne di stringhe, potresti volere che la tua applicazione esegua la ricerca in entrambe le colonne senza distinguere da quale colonna provengono le corrispondenze.
In Spanner, esistono due modi per farlo:
- Tokenizza le parole separatamente e concatena i
TOKENLIST
risultanti (opzione consigliata). - Concatena le stringhe e tokenizza il risultato.
Con il secondo approccio si verificano due problemi:
- Se vuoi indicizzare
Title
oStudio
singolarmente, oltre a indicizzarli in unTOKENLIST
combinato, lo stesso testo viene tokenizzato due volte. Di conseguenza, le transazioni utilizzano più risorse. - Una ricerca di frasi interessa entrambi i campi. Ad esempio, se
@p
è impostato su"Blue Note"
, corrisponde a una riga che contiene siaTitle
="Big Blue Note" cheStudio
="Blue Note Studios".
Il primo approccio risolve questi problemi perché una frase corrisponde a un solo campo
e ogni campo di stringa viene tokenizzato una sola volta se sono indicizzati sia i singoli sia i TOKENLIST
combinati. Anche se ogni campo di stringa viene tokenizzato una sola volta,
i TOKENLIST
risultanti vengono archiviati separatamente nell'indice.
Tokenizza le parole separatamente e concatena le TOKENLIST
L'esempio seguente tokenizza ogni parola e utilizza
TOKENLIST_CONCAT
per concatenare i TOKENLIST
:
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
PostgreSQL utilizza
spanner.tokenlist_concat
per la concatenazione. Il parametro di query $1
è associato 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);
Tieni presente che tokenlist_concat
non chiama title_tokens
o studio_tokens
, ma chiama spanner.tokenize_fulltext(title)
e
spanner.tokenize_fulltext(studio)
. Questo perché PostgreSQL
non supporta i riferimenti alle colonne generate all'interno di altre colonne
generate. spanner.tokenlist_concat
deve chiamare le funzioni di tokenizzazione e non fare riferimento direttamente alle colonne della lista di token.
La concatenazione TOKENLIST
può essere implementata anche interamente a livello di query.
Per ulteriori informazioni, consulta la sezione Concatenazione TOKENLIST
lato query.
TOKENLIST_CONCAT
è supportato sia per le ricerche a testo intero sia per quelle con sottostringa.
Spanner non ti consente di combinare tipi di tokenizzazione, ad esempio TOKENIZE_FULLTEXT
e TOKENIZE_SUBSTRING
nella stessa chiamata TOKENLIST_CONCAT
.
In GoogleSQL, la definizione delle colonne di testo TOKENLIST
può essere modificata nelle colonne non archiviate per aggiungere altre colonne. Questa operazione è utile quando vuoi aggiungere un'altra colonna a TOKENLIST_CONCAT
. La modifica dell'espressione della colonna generata non esegue il backfill delle righe esistenti nell'indice.
Concatena le stringhe e tokenizza il risultato
L'esempio seguente concatena le stringhe e tokenizza il risultato:
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);
Concatenazione TOKENLIST
lato query
Il compromesso con l'indicizzazione del TOKENLIST
concatenato è che aumenta il costo di archiviazione e scrittura. Ora ogni token viene archiviato sul disco due volte:
una volta in un elenco di post del TOKENLIST
originale e una volta in un elenco di post
del TOKENLIST
combinato. La concatenazione lato query delle colonne TOKENLIST
consente di evitare questo costo, ma la query utilizza più risorse di calcolo.
Per concatenare più TOKENLIST
, utilizza la funzione
TOKENLIST_CONCAT
nella query
SEARCH
. Per questa sezione utilizziamo lo schema di esempio seguente:
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);
La seguente query cerca le righe che contengono i token "blu"
e "nota" in qualsiasi posizione nelle colonne Title
e Studio
. Sono incluse
le righe con "blu" e "nota" nella colonna Title
, "blu" e "nota" nella colonna
Studio
, "blu" nella colonna Title
e "nota" nella colonna Studio
o viceversa.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(TOKENLIST_CONCAT([AlbumTitle_Tokens, Studio_Tokens]), 'blue note')
PostgreSQL
Questo esempio utilizza
spanner.search
con
spanner.tokenlist_concat
.
SELECT albumid
FROM albums
WHERE spanner.search(spanner.tokenlist_concat(ARRAY[albumtitle_tokens, studio_tokens]), 'blue note')
La concatenazione TOKENLIST
lato scrittura e lato query produce risultati identici.
La scelta tra i due è un compromesso tra il costo del disco e il costo delle query.
In alternativa, un'applicazione potrebbe cercare in più colonne TOKENLIST
e utilizzare
OR
insieme alla funzione 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')
Tuttavia, la semantica è diversa. Non corrisponde agli album in cuiAlbumTitle_Tokens
ha "blu", ma non "nota" e Studio_Tokens
ha
"nota", ma non "blu".
Passaggi successivi
- Scopri di più sulle query di ricerca a testo intero.
- Scopri di più sugli indici di ricerca.