Questa pagina descrive come concatenare TOKENLIST in un
indice di ricerca quando configuri lo schema
o in una query di ricerca quando esegui una ricerca full-text in Spanner.
Combinare TOKENLIST in un indice di ricerca
A volte, devi fare in modo che la tua applicazione esegua ricerche in singoli campi. In altri casi, l'applicazione deve eseguire la ricerca in tutti i campi. Ad esempio, in una tabella con due colonne di stringhe, potresti voler che la tua applicazione esegua ricerche 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 gli
TOKENLISTrisultanti (opzione consigliata). - Concatenare le stringhe e tokenizzare il risultato.
Con il secondo approccio, ci sono due problemi:
- Se vuoi indicizzare
TitleoStudiosingolarmente, oltre a indicizzarli in unTOKENLISTcombinato, lo stesso testo viene tokenizzato due volte. Ciò fa sì che le transazioni utilizzino più risorse. - La ricerca di una frase si estende a entrambi i campi. Ad esempio, se
@pè impostato su"Blue Note", corrisponde a una riga che contiene siaTitle="Big Blue Note" siaStudio="Blue Note Studios".
Il primo approccio risolve questi problemi perché una frase corrisponde a un solo campo
e ogni campo stringa viene tokenizzato una sola volta se vengono indicizzati sia i TOKENLIST singoli che quelli combinati. Anche se ogni campo stringa viene tokenizzato una sola volta,
i TOKENLIST risultanti vengono memorizzati separatamente nell'indice.
Tokenizza le parole separatamente e concatenale TOKENLIST
Il seguente esempio 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 ricerca $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 che si trovano all'interno di altre colonne
generate. spanner.tokenlist_concatdeve chiamare le funzioni di tokenizzazione e non
fare riferimento direttamente alle colonne tokenlist.
La concatenazione di TOKENLIST può essere implementata anche interamente sul lato della query.
Per maggiori informazioni, consulta la sezione Concatenazione TOKENLIST
lato query.
TOKENLIST_CONCAT è supportato sia per la ricerca a testo intero sia per la ricerca di sottostringhe.
Spanner non 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 colonne aggiuntive. Questa opzione è utile quando
vuoi aggiungere una colonna aggiuntiva a TOKENLIST_CONCAT. La modifica dell'espressione della colonna generata non esegue il backfill delle righe esistenti nell'indice.
Concatenare stringhe e tokenizzare 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 di TOKENLIST concatenati è che aumenta i costi di archiviazione e scrittura. Ora ogni token viene memorizzato due volte sul disco:
una volta in un elenco di pubblicazione del suo TOKENLIST originale e una volta in un elenco di pubblicazione
del TOKENLIST combinato. La concatenazione lato query delle colonne TOKENLIST
evita 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 il seguente schema di esempio:
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 "blue"
e "note" in qualsiasi punto delle colonne Title e Studio. Sono incluse
le righe con "blue" e "note" nella colonna Title, "blue" e "note" nella
colonna Studio e "blue" nella colonna Title e "note" 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 lato scrittura e lato query TOKENLIST 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 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, ha una semantica diversa. Non corrisponde agli album in cui
AlbumTitle_Tokens contiene "blue", ma non "note" e Studio_Tokens contiene
"note", ma non "blue".
Passaggi successivi
- Scopri di più sulle query di ricerca full-text.
- Scopri di più sugli indici di ricerca.