Espansione delle query di ricerca

Questa pagina descrive come utilizzare il miglioramento delle query nell'ambito di una ricerca full-text.

Per aumentare la probabilità di trovare risultati pertinenti, Spanner offre funzionalità avanzate che espandono la query di ricerca per includere termini correlati, sinonimi e correzioni ortografiche. Spanner offre le seguenti opzioni per il miglioramento delle query:

Query migliorata

Per utilizzare la query migliorata, imposta enhance_query=>true nella funzione SEARCH. Spanner espande automaticamente le query di ricerca includendo termini e sinonimi correlati, applicando la derivazione e apportando correzioni ortografiche. Ad esempio, quando si utilizza la query migliorata, la query di ricerca hotl cal corrisponde all'album Hotel California.

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'hotl cal', enhance_query=>true)

PostgreSQL

SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'hotl cal', enhance_query=>true)

enhance_query è un'opzione di query che non influisce sulla tokenizzazione. Puoi utilizzare lo stesso indice di ricerca con o senza enhance_query.

Google migliora costantemente gli algoritmi di miglioramento delle query. Di conseguenza, una query con enhance_query => true potrebbe produrre risultati leggermente diversi nel tempo.

Quando viene utilizzato enhance_query, la latenza potrebbe aumentare a causa del sovraccarico dovuto all'espansione della query di ricerca e all'esecuzione della query più grande risultante.

Dizionari personalizzati

Puoi utilizzare dizionari personalizzati con la ricerca full-text di Spanner per definire i sinonimi dei termini nel tuo set di dati. Questa funzionalità è utile per acquisire sinonimi, acronimi, termini equivalenti e altre varianti di parole per migliorare il recupero dei risultati di ricerca.

Creare una tabella di dizionari personalizzati

Un dizionario personalizzato è una tabella creata dall'utente contenente coppie chiave-valore di termini e relativi sinonimi. Per crearne uno, includi l'opzione fulltext_dictionary_table = true nell'istruzione CREATE TABLE. La tabella deve avere due colonne:

  • Key: una colonna di stringhe non nullable per il termine da espandere con i sinonimi.
  • Value: una colonna di array di stringhe non nullable per un array di sinonimi della chiave.

Nella tabella non possono essere presenti colonne diverse da Key e Value. Se un termine di ricerca corrisponde a una Key nel dizionario, la ricerca viene espansa per includere tutti i sinonimi corrispondenti in Value insieme al termine chiave stesso. L'esempio seguente crea una tabella di dizionari personalizzati denominata MyCustomDictionary. Durante la creazione, devi anche impostare l'opzione della tabella fulltext_dictionary_table=true su questa tabella.

GoogleSQL

CREATE TABLE MyCustomDictionary (
  Key STRING(MAX) NOT NULL,
  Value ARRAY<STRING(MAX)> NOT NULL,
) PRIMARY KEY(Key),
OPTIONS (fulltext_dictionary_table = true);

PostgreSQL

CREATE TABLE mycustomdictionary (
  key character varying  NOT NULL,
  value character varying [] NOT NULL,
  PRIMARY KEY(key)
)  WITH ( type = 'fulltext_dictionary')

Dopo aver creato la tabella, inserisci i sinonimi:

GoogleSQL

INSERT INTO MyCustomDictionary (Key, Value) VALUES
('album', ['vinyl', 'cassette']),
('edm', ['electronic dance music']);

PostgreSQL

INSERT INTO mycustomdictionary (key, value) VALUES
('album', ARRAY['vinyl', 'cassette']),
('edm', ARRAY['electronic dance music']);

Quando compili la tabella, tieni presente quanto segue:

  • Le chiavi devono essere parole singole.
  • I valori possono essere parole singole o frasi di più parole. Se un valore contiene più parole, viene trattato come una ricerca di frasi durante l'espansione della query.
  • Tutte le chiavi e i valori devono essere in minuscolo. In questo modo, corrispondono ai token di ricerca, che vengono convertiti in minuscolo dal tokenizer predefinito.

L'espansione della ricerca si verifica solo quando un termine di ricerca corrisponde a una Key. Se un termine di ricerca corrisponde a un sinonimo in Value, ma non a una Key, la ricerca non viene espansa. Se hai bisogno di una mappatura bidirezionale (ad esempio, in modo che la ricerca di vinyl o cassette trovi anche album), devi anche inserire le mappature inverse nella tabella del dizionario. L'esempio seguente mostra come inserire mappature bidirezionali per album, vinyl e cassette:

GoogleSQL

INSERT INTO MyCustomDictionary (Key, Value)
-- 1. Insert album -> vinyl, cassette
SELECT 'album', ['vinyl', 'cassette']
UNION ALL
-- 2. Insert vinyl -> album and cassette -> album
SELECT syn, ['album']
FROM UNNEST(['vinyl', 'cassette']) AS syn;

PostgreSQL

INSERT INTO mycustomdictionary (key, value)
-- 1. Insert album -> vinyl, cassette
SELECT 'album', ARRAY['vinyl', 'cassette']
UNION ALL
-- 2. Insert vinyl -> album and cassette -> album
SELECT syn, ARRAY['album']
FROM unnest(ARRAY['vinyl', 'cassette']) AS syn;

Utilizzare un dizionario personalizzato nelle query di ricerca

Per utilizzare un dizionario personalizzato, specifica il nome della tabella del dizionario nell'argomento dictionary della funzione SEARCH.

  • Se un termine di ricerca è una chiave nel dizionario, SEARCH cerca anche i relativi valori. Il termine album corrisponde ai messaggi contenenti vinyl o cassette.

    GoogleSQL

    SELECT MessageId, Body
    FROM Messages
    WHERE SEARCH(Body_Tokens, 'album', dictionary=>'MyCustomDictionary');
    

    PostgreSQL

    SELECT messageid, body
    FROM messages
    WHERE spanner.search(body_tokens, 'album', dictionary=>'mycustomdictionary');
    
  • Quando un valore del dizionario contiene più parole, ad esempio electronic dance music per la chiave edm, viene trattato come una ricerca di frasi. Ciò significa che i termini devono apparire in modo adiacente e nell'ordine esatto specificato per essere considerati una corrispondenza. Ad esempio, la query seguente restituisce risultati contenenti la frase esatta "electronic dance music", ma non corrisponde a "dance electronic music". Questa funzionalità è utile principalmente per espandere gli acronimi e può essere utilizzata nel seguente modo:

    GoogleSQL

    SELECT MessageId, Body
    FROM Messages
    WHERE SEARCH(Body_Tokens, 'edm', dictionary=>'MyCustomDictionary');
    

    PostgreSQL

    SELECT messageid, body
    FROM messages
    WHERE spanner.search(body_tokens, 'edm', dictionary=>'mycustomdictionary');
    

Staleness della ricerca nel dizionario

Per impostazione predefinita, le voci del dizionario personalizzato vengono lette con una staleness massima di 15 secondi. In questo modo si riduce il sovraccarico dell'operazione di lettura, perché la lettura dei dati con una certa staleness è più efficiente della lettura dei dati più recenti. Di conseguenza, le modifiche alle voci del dizionario potrebbero richiedere fino a 15 secondi per essere visualizzate nelle query di ricerca. Puoi eseguire l'override di questo comportamento nei seguenti modi:

  • Utilizzando l'opzione della tabella fulltext_dictionary_staleness.
  • Utilizzando l'hint della query fulltext_dictionary_staleness per un controllo più granulare.

Se vengono utilizzati entrambi, l'hint della query sostituisce l'opzione della tabella.

Opzione della tabella fulltext_dictionary_staleness

Puoi impostare l'opzione fulltext_dictionary_staleness per la tabella del dizionario. Tutte le query che utilizzano questa tabella del dizionario utilizzano questo valore di staleness, a meno che non venga sostituito dall'hint della query.

GoogleSQL

L'esempio seguente mostra come CREATE una tabella con l'opzione fulltext_dictionary_staleness:

CREATE TABLE MyCustomDictionary (
  Key STRING(MAX) NOT NULL,
  Value ARRAY<STRING(MAX)> NOT NULL,
) PRIMARY KEY(Key),
OPTIONS (
  fulltext_dictionary_table = true,
  fulltext_dictionary_staleness = '5s'
);

L'esempio seguente mostra come ALTER la tabella per modificare o impostare l'opzione fulltext_dictionary_staleness:

ALTER TABLE MyCustomDictionary SET OPTIONS (
  fulltext_dictionary_staleness = '60s'
);

PostgreSQL

L'esempio seguente mostra come CREATE una tabella con l'opzione fulltext_dictionary_staleness:

-- Create with 5s staleness
CREATE TABLE mycustomdictionary (
  key character varying NOT NULL,
  value character varying[]  NOT NULL,
  PRIMARY KEY(key)
) WITH (
  type = 'fulltext_dictionary',
  fulltext_dictionary_staleness = '5s'
);

L'interfaccia PostgreSQL non supporta ALTER la tabella per modificare o impostare l'opzione fulltext_dictionary_staleness.

Hint della query fulltext_dictionary_staleness

Per un controllo più granulare, puoi utilizzare l'hint della query fulltext_dictionary_staleness per specificare una staleness diversa per una singola query. Questo hint sostituisce l'impostazione a livello di tabella.

L'esempio seguente utilizza un hint per eseguire ricerche nella tabella del dizionario con staleness zero. In questo modo, vengono lette le voci del dizionario più recenti. Questo approccio può aumentare la latenza delle query perché la lettura dei dati più recenti è meno efficiente rispetto alla possibilità di una certa staleness.

GoogleSQL

@{fulltext_dictionary_staleness="0s"}
SELECT MessageId, Body
FROM Messages
WHERE SEARCH(Body_Tokens, 'Bill', dictionary=>'MyCustomDictionary');

PostgreSQL

/*@ fulltext_dictionary_staleness='0s' */
SELECT messageid, body
FROM messages
WHERE spanner.search(body_tokens, 'Bill', dictionary=>'mycustomdictionary');

Limitazioni note con le tabelle di dizionari personalizzati

  • Il supporto per l'utilizzo di Spanner Import ed Export con le tabelle di dizionari personalizzati è limitato.
  • Le tabelle di dizionari personalizzati devono essere create nello schema predefinito e non possono essere create in schemi denominati.
  • Le tabelle di dizionari personalizzati supportano solo il dialetto della query SEARCH predefinito.

Combinare dizionari personalizzati con query migliorata

Puoi combinare i sinonimi dei dizionari personalizzati con enhanced query impostando sia dictionary sia enhance_query=>true nella funzione SEARCH. Il miglioramento delle query può espandere le query con sinonimi comuni o correzioni ortografiche, mentre i dizionari personalizzati ti consentono di definire le tue espansioni. Ad esempio, se enhance_query espande album per includere record e MyCustomDictionary mappa album a ['vinyl', 'cassette'], la query seguente corrisponde ai messaggi contenenti album, record, vinyl o cassette:

GoogleSQL

SELECT MessageId, Body
FROM Messages
WHERE SEARCH(Body_Tokens, 'album', enhance_query=>true, dictionary=>'MyCustomDictionary');

PostgreSQL

SELECT messageid, body
FROM messages
WHERE spanner.search(body_tokens, 'album', enhance_query=>true, dictionary=>'mycustomdictionary');

Quando entrambi i miglioramenti sono abilitati, operano in modo indipendente sui termini di ricerca originali e i termini generati da un miglioramento non vengono utilizzati come input per l'altro.

Passaggi successivi