Questa pagina descrive la funzione SEARCH
e la modalità di query avanzata, che vengono utilizzate per eseguire query di ricerca a testo intero sulle tabelle Spanner.
Eseguire una query su un indice di ricerca
Spanner fornisce la funzione
SEARCH
da utilizzare per le query sull'indice di ricerca. Un caso d'uso di esempio è un'applicazione in cui gli utenti inseriscono del testo in una casella di ricerca e l'applicazione invia l'input utente direttamente alla funzione SEARCH
. La funzione "SEARCH" userebbe quindi un indice di ricerca per trovare il testo.
La funzione SEARCH
richiede due argomenti:
- Un nome di indice di ricerca
- Una query di ricerca
La funzione SEARCH
funziona solo quando è definito un indice di ricerca. La funzione SEARCH
può essere combinata con qualsiasi costrutto SQL arbitrario, ad esempio filtri,
aggregazioni o join.
La funzione SEARCH
non può essere utilizzata con le query sulle transazioni.
La seguente query utilizza la funzione SEARCH
per restituire tutti gli album che contengono friday
o monday
nel titolo:
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'friday OR monday')
Query di ricerca
Per impostazione predefinita, la query di ricerca utilizza la sintassi della query di ricerca non elaborata. È possibile specificare sintassi alternative utilizzando l'argomento dialect
.
Dialetto rquery
Il dialetto predefinito è query di ricerca non elaborata. Spanner utilizza un linguaggio specifico per il dominio (DSL) chiamato rquery.
Il linguaggio rquery segue le stesse regole del tokenizzatore di testo normale quando suddivide la query di ricerca inserita in termini distinti. Sono incluse le lingue asiatiche.
Per informazioni sull'utilizzo di rquery, consulta la pagina sulla sintassi di rquery.
parole dialetto
Il dialetto delle parole è simile a rquery, ma più semplice. Non utilizza operatori speciali. Ad esempio, OR
viene trattato come termine di ricerca anziché come operatore di disgiunzione. Le virgolette doppie vengono gestite come punteggiatura anziché come ricerca di frasi e vengono ignorate.
Con il dialetto delle parole, AND
viene applicato implicitamente a tutti i termini ed è obbligatorio durante la corrispondenza. Segue le stesse regole del tokenizzatore di testo normale quando suddivide la query di ricerca inserita in termini.
Per informazioni sull'utilizzo del dialetto delle parole, consulta la sintassi di words.
words_phrase dialect
Il dialetto words_phrase non utilizza operatori speciali e tutti i termini vengono trattati come una frase, il che significa che devono essere adiacenti e nell'ordine specificato.
Come rquery, il dialetto words_phrase segue le stesse regole dello tokenizer di testo normale per suddividere la query di ricerca inserita in termini.
Per informazioni sull'utilizzo del dialetto words_phrase, consulta la sintassi delle frasi di parole.
Modalità di query avanzata
Spanner offre due modalità di ricerca a testo intero: una ricerca di base basata su token e una modalità più avanzata chiamata enhance_query
. Se è attivata,
enhance_query
espande la query di ricerca per includere termini e sinonimi correlati,
aumentando la probabilità di trovare risultati pertinenti.
Per attivare questa opzione, imposta l'argomento facoltativo enhance_query=>true
nella funzione SEARCH
. Ad esempio, la query di ricerca hotl cal
corrisponde all'album
Hotel California
.
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'hotl cal', enhance_query=>true)
La modalità enhance_query
è un'opzione al momento della query. 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 la modalità enhance_query
è attiva, potrebbe aumentare il numero di termini
che la funzione SEARCH
sta cercando, il che potrebbe aumentare leggermente la latenza.
Ad esempio, la seguente query utilizza un timeout di tre secondi e non va a buon fine se enhance_query
non è disponibile:
@{require_enhance_query=true, enhance_query_timeout_ms=3000}
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'fast car', enhance_query=>true)
Per ulteriori informazioni sull'utilizzo dell'opzione enhance_query
, consulta la funzione RICERCA.
Requisiti delle query SQL
Una query SQL deve soddisfare diverse condizioni per utilizzare un indice di ricerca. Se queste condizioni non sono soddisfatte, la query utilizza un piano di query alternativo o non va a buon fine se non esiste un piano alternativo.
Le query devono soddisfare le seguenti condizioni:
Le funzioni
SEARCH
eSEARCH_SUBSTRING
richiedono un indice di ricerca. Spanner non supporta queste funzioni nelle query contro la tabella di base o gli indici secondari.Gli indici partizionati devono avere tutte le colonne di partizione vincolate da una condizione di uguaglianza nella clausola
WHERE
della query.Ad esempio, se un indice di ricerca è definito come
PARTITION BY x, y
, la query deve avere una congiuntiva nella clausolaWHERE
dix = <parameter or constant> AND y = <parameter or constant>
. L'indice di ricerca non viene preso in considerazione dall'ottimizzatore delle query se manca questa condizione.Tutte le colonne
TOKENLIST
a cui fanno riferimento gli operatoriSEARCH
eSEARCH_SUBSTRING
devono essere indicizzate nello stesso indice di ricerca.Ad esempio, prendi in considerazione la seguente definizione di tabella e indice:
CREATE TABLE Albums ( AlbumId STRING(MAX) NOT NULL, AlbumTitle STRING(MAX), AlbumStudio STRING(MAX), AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN, AlbumStudio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumStudio)) HIDDEN ) PRIMARY KEY(AlbumId); CREATE SEARCH INDEX AlbumsTitleIndex ON Albums(AlbumTitle_Tokens); CREATE SEARCH INDEX AlbumsStudioIndex ON Albums(AlbumStudio_Tokens);
La seguente query non va a buon fine perché non esiste un singolo indice di ricerca che indicizzi sia
AlbumTitle_Tokens
siaAlbumStudio_Tokens
:SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, @p1) AND SEARCH(AlbumStudio_Tokens, @p2)
Se la colonna dell'ordinamento è nullable, sia lo schema sia la query devono escludere le righe in cui la colonna dell'ordinamento è NULL. Per informazioni dettagliate, consulta Ordine di ordinamento dell'indice di ricerca.
Se l'indice di ricerca è filtrato per NULL, la query deve includere la stessa expressione di filtro NULL utilizzata in un indice. Per ulteriori dettagli, consulta Indici di ricerca con filtro NULL.
Gli indici di ricerca e le funzioni di ricerca non sono supportati in DML, DML partizionato o query partizionate.
Gli indici di ricerca e le funzioni di ricerca vengono in genere utilizzati nelle transazioni di sola lettura. Se i requisiti dell'applicazione consentono risultati non aggiornati, ti consigliamo di eseguire query di ricerca con una durata di inattività di almeno 10 secondi. Per ulteriori informazioni, consulta la sezione Leggere i dati non aggiornati. Ciò è particolarmente utile per query di ricerca di grandi dimensioni che si espandono a più gruppi Paxos.
Gli indici di ricerca e le funzioni di ricerca non sono consigliati nelle transazioni di lettura/scrittura. Durante l'esecuzione, le query di ricerca bloccano un'intera partizione dell'indice. Di conseguenza, un tasso elevato di query di ricerca nelle transazioni di lettura/scrittura potrebbe causare conflitti di blocco che generano picchi di latenza. Per impostazione predefinita, gli indici di ricerca non vengono selezionati automaticamente nelle transazioni di lettura/scrittura. Se una query è costretta a utilizzare un indice di ricerca in una transazione di lettura/scrittura, non va a buon fine per impostazione predefinita. Inoltre, non andrà a buon fine se la query contiene una delle funzioni di ricerca. Questo comportamento puoi essere ignorato con l'opzione
@{ALLOW_SEARCH_INDEXES_IN_TRANSACTION=TRUE}
a livello di dichiarazione (ma le query sono comunque soggette a conflitti di blocco).
Una volta soddisfatte le condizioni di idoneità dell'indice, l'ottimizzatore delle query tenta di accelerare le condizioni di query non di testo (come Rating > 4
). Se l'indice di ricerca non include la colonna TOKENLIST
appropriata, la condizione non viene accelerata e rimane una condizione residua.
Parametri di query
Gli argomenti della query di ricerca vengono specificati come un valore letterale o un parametro di query. Ti consigliamo di utilizzare parametri di ricerca per la ricerca full-text anziché le stringhe litteali quando gli argomenti consentono valore parametro di query.
Selezione dell'indice
In genere, Spanner seleziona l'indice più efficiente per una query utilizzando la definizione del modello in base al costo. Tuttavia, l'istruzione FORCE_INDEX
indica esplicitamente a Spanner di utilizzare un indice di ricerca specifico. Ad esempio, il codice seguente mostra come forzare Spanner a utilizzare AlbumsIndex
:
SELECT AlbumId
FROM Albums @{FORCE_INDEX=AlbumsIndex}
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
Se l'indice di ricerca specificato non è idoneo, la query non va a buon fine, anche se sono presenti altri indici di ricerca idonei.
Snippet nei risultati di ricerca
Uno snippet è un frammento di testo estratto da una determinata stringa che fornisce agli utenti un'idea di cosa contiene un risultato di ricerca e del motivo per cui è pertinente alla loro query.
Ad esempio, Gmail utilizza gli snippet per indicare la parte di un'email che corrisponde alla query di ricerca:
La generazione di uno snippet da parte del database presenta diversi vantaggi:
- Comodità: non è necessario implementare la logica per generare snippet da una query di ricerca.
- Efficienza: gli snippet riducono le dimensioni dell'output del server.
La funzione SNIPPET
crea lo snippet. Restituisce la parte pertinente del valore della stringa originale insieme alle posizioni dei caratteri da evidenziare. Il
client può quindi scegliere come mostrare lo snippet all'utente finale (ad esempio,
utilizzando il testo evidenziato o in grassetto). La funzione SNIPPET
rimuove tutti i tag HTML dalla stringa originale.
Ad esempio, il seguente codice utilizza SNIPPET
per recuperare il testo da AlbumTitle
:
SELECT AlbumId, SNIPPET(AlbumTitle, "Fast Car")
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "Fast Car")
Passaggi successivi
- Scopri come determinare il ranking dei risultati di ricerca.
- Scopri come eseguire una ricerca di sottostringhe.
- Scopri come paginare i risultati di ricerca.
- Scopri come combinare query a testo intero e non di testo.
- Scopri come eseguire ricerche in più colonne.