In questa pagina vengono descritti la funzione SEARCH
e la modalità di query avanzata,
utilizzata per eseguire una ricerca a testo intero
sulle tabelle Spanner.
Eseguire una query su un indice di ricerca
Spanner fornisce
SEARCH
per le query dell'indice di ricerca. La funzione SEARCH
richiede due argomenti:
- Un nome di indice di ricerca
- Una query rquery
La funzione SEARCH
funziona solo quando viene definito un indice di ricerca. La funzione SEARCH
può essere combinata con qualsiasi costrutto SQL arbitrario, ad esempio filtri,
aggregazioni o join.
La seguente query utilizza la funzione SEARCH
per restituire tutti gli album con
friday
o monday
nel titolo:
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'friday OR monday')
Il linguaggio rquery
Il secondo argomento della funzione SEARCH
è una lingua specifica del dominio (DSL)
denominato rquery. Il linguaggio rquery è simile al linguaggio degli utenti internet
che abitualmente usano su google.com:
- Più termini implicano
AND
. Ad esempio, "Big Time" equivale abig AND time
. L'operazione
OR
implica una disgiunzione tra due termini, ad esempiobig OR time
. L'istruzioneSEARCH(tl, 'big time OR fast car')
equivale a:SEARCH(tl, 'big') AND (SEARCH(tl, 'time') OR SEARCH(tl, 'fast')) AND SEARCH(tl, 'cat');
OR
si applica solo ai due termini adiacenti. Ad esempio, la ricerca l'espressionehappy friday OR monday
cerca tutti i documenti contenenti il terminehappy
e il terminefriday
omonday
.Le virgolette doppie indicano una ricerca di una frase. Ad esempio, la query rquery
"big cat"
corrisponde a "Ho un grande gatto", ma non a "Il mio gatto è grande".L'operatore
AROUND
trova corrispondenze con i termini che si trovano entro una certa distanza da tra loro. Ad esempio, rquerybig AROUND cat
corrisponde a "big, white, gatto morbido", ma non corrisponde a "un cane grande era seduto accanto a un gatto piccolo". Per impostazione predefinita, vengono utilizzati termini separati da al massimo cinque posizioni. Per regolare la distanza, passa un argomento all'operatoreAROUND
. Spanner supporta due sintassi perAROUND
:big AROUND(10) cat
big AROUND 10 cat
L'operatore
AROUND
, se utilizzato all'interno di una frase, può trovare corrispondenze tra termini che si trovano a una determinata distanza l'uno dall'altro e nello stesso ordine (il valore predefinito è cinque token). Ad esempio, la stringabig AROUND cat
corrisponde a "gatto grande bianco e soffice", ma non a "il gatto era grande".La negazione di un singolo token è espressa con un trattino (
-
). Ad esempio,-dog
corrisponde a tutti i documenti che non contengono il terminedog
.Generalmente la punteggiatura viene ignorata. Ad esempio, "Big Time!". equivale a "Big Time".
La ricerca non fa distinzione tra maiuscole e minuscole. Ad esempio, "Big Time" corrisponde a "big time".
Gli operatori
The OR
eAROUND
sono sensibili alle maiuscole. Il carattere barra verticale (|
) è una scorciatoia perOR
.
Come funziona il linguaggio rquery
Il linguaggio rquery segue le stesse regole tokenizzatore di testo normale quando suddividi la stringa di input in termini distinti. È inclusa la segmentazione delle lingue asiatiche.
Molte applicazioni offrono agli utenti un modo per inserire una query di ricerca in una
casella di ricerca. Il modo più semplice per integrare queste query degli utenti finali è inviare l'input dell'utente direttamente alla funzione SEARCH
.
La seguente tabella spiega il significato di varie stringhe rquery:
rquery | Spiegazione |
---|---|
Big Cat |
Restituisce i documenti che contengono entrambi i termini "grande" e "gatto". |
cat OR dog |
Corrisponde ai documenti che contengono almeno uno dei termini "gatto" e "cane". |
-cat |
Corrisponde a tutti i documenti che non contengono il termine "gatto". |
"big dog" -"big cat" |
Restituisce i documenti che contengono due termini adiacenti "grandi" e "cane", ma non contengono elementi "big" adiacenti e "gatto". Ad esempio, questa query corrisponde a "Ho un cane grande e un gatto piccolo", ma non corrisponde a "Ho un grande cane e un grande gatto". |
cat|dog |
È lo stesso che gatto OPPURE cane. |
and OR or |
Corrisponde ai documenti che contengono il termine "and" o il termine "or" (l'operatore OR deve essere in maiuscolo) |
Modalità di query avanzata
Oltre a una ricerca a testo intero puramente basata su token, Spanner supporta una modalità più completa chiamata enhance_query
. Se attivata, questa modalità si estende
la query di ricerca per includere altre varianti dei token. Queste riscritture aumentano le ricerche
richiamo.
Per abilitare questa opzione, imposta l'argomento facoltativo enhance_query=>true
nel
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 tempo query. Questa operazione non influisce sulla tokenizzazione.
Puoi utilizzare lo stesso indice di ricerca con o senza enhance_query
.
Google migliora continuamente 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, il numero di termini potrebbe aumentare
cercata dalla funzione SEARCH
e che potrebbe generare un aumento leggermente
una latenza di pochi millisecondi.
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, 'cat', enhance_query=>true)
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. Query relative a 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 è considerato dallo strumento di ottimizzazione delle query se questa condizione è mancante.Tutte le colonne
TOKENLIST
a cui fanno riferimentoSEARCH
eSEARCH_SUBSTRING
gli operatori devono essere indicizzati nello stesso indice di ricerca.Ad esempio, considera 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 di ordinamento è con valore null, sia lo schema sia la query devono escludi le righe in cui la colonna di ordinamento è NULL. Consulta Ordinamento dell'indice di ricerca per maggiori dettagli.
Se l'indice di ricerca è filtrato per NULL, la query deve includere lo stesso Espressione di filtro NULL utilizzata in un indice. Per maggiori dettagli, consulta la sezione Indici di ricerca con filtro NULL.
Gli indici di ricerca non sono supportati in DML, in DML partizionati e partizionati query .
Gli indici di ricerca vengono generalmente utilizzati transazioni di sola lettura. Se i requisiti dell'applicazione consentono risultati inattivi, consigliamo di eseguire con una durata di inattività di almeno 10 secondi. Per ulteriori informazioni le informazioni, vedi Lettura di dati inattivi. Ciò è particolarmente utile per query di ricerca di grandi dimensioni che si espandono a più gruppi Paxos.
Gli indici di ricerca non sono consigliati in transazioni di lettura/scrittura. Durante l'esecuzione, le query di ricerca bloccano un'intera partizione dell'indice. come un risultato, un'elevata percentuale di query di ricerca nelle transazioni di lettura/scrittura potrebbe conflitti di blocco che portano a picchi di latenza. Per impostazione predefinita, gli indici di ricerca selezionate automaticamente nelle transazioni di lettura/scrittura. Se una query viene forzata utilizza un indice di ricerca in una transazione di lettura/scrittura non riuscita per impostazione predefinita. Questo comportamento può essere ignorato con il suggerimento a livello di dichiarazione
@{ALLOW_SEARCH_INDEXES_IN_TRANSACTION=TRUE}
(ma le query sono comunque soggette a conflitti di blocco).
Una volta soddisfatte le condizioni di idoneità dell'indice, lo strumento di ottimizzazione delle query
accelerare condizioni di query non testuali (come Rating > 4
). Se l'indice di ricerca
non include la colonna TOKENLIST
appropriata, la condizione non è
ha un'accelerazione e rimane una condizione residua.
Parametri di query
rquery e altri parametri come OFFSET
sono specificati come valore letterale
un parametro di query.
Ti consigliamo di utilizzare parametri di ricerca anziché valori letterali stringa. Le query parametrizzate hanno tassi di hit della cache delle query migliori, il che si traduce in una latenza delle query inferiore e in un utilizzo complessivo della CPU inferiore.
Ad esempio, invece di utilizzare una query come la seguente:
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, 'cat')
utilizza la seguente sintassi:
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, @p)
Spanner esegue l'ottimizzatore delle query su testo SQL distinto. Minore è il numero di testi SQL distinti utilizzati dall'applicazione, minore è il numero di volte viene richiamata.
Ordinamento dell'indice di ricerca
Il comportamento dell'ordinamento degli indici di ricerca è diverso da quello secondario indici.
Ad esempio, considera la seguente tabella:
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
ReleaseTimestamp INT64 NOT NULL,
AlbumName STRING(MAX),
AlbumName_Token TOKENLIST AS (TOKEN(AlbumName)) HIDDEN
) PRIMARY KEY(AlbumId);
L'applicazione potrebbe definire un indice secondario per la ricerca di informazioni utilizzando
AlbumName
ordinati per ReleaseTimestamp
:
CREATE INDEX AlbumsSecondaryIndex ON Albums(AlbumName, ReleaseTimestamp DESC);
L'indice di ricerca equivalente è il seguente (utilizza la tokenizzazione con corrispondenza esatta, poiché gli indici secondari non supportano le ricerche full-text):
CREATE SEARCH INDEX AlbumsSearchIndex
ON Albums(AlbumName_Token)
ORDER BY ReleaseTimestamp DESC;
L'ordinamento dell'indice di ricerca deve essere conforme alle seguenti regole:
- Utilizza le colonne
INT64
solo per l'ordine di ordinamento di un indice di ricerca. Le colonne con dimensioni arbitrarie utilizzano troppe risorse nell'indice di ricerca perché Spanner deve memorizzare il docid accanto a ogni token. In particolare, la colonna di ordinamento non può utilizzare il tipoTIMESTAMP
perchéTIMESTAMP
usa la precisione in nanosecondi, non rientra in un numero intero a 64 bit. Le colonne dell'ordine di ordinamento non devono essere
NULL
. Esistono due modi per soddisfare questo requisito:- Dichiara la colonna dell'ordinamento come
NOT NULL
. - Configura l'indice per escludere i valori NULL.
- Dichiara la colonna dell'ordinamento come
In pratica, per determinare l'ordinamento viene spesso utilizzato un timestamp. Un comune è quella di utilizzare microsecondi poiché lo standard Unix epoch per questi timestamp.
In genere le applicazioni recuperano per primi i dati più recenti utilizzando un indice di ricerca in ordine decrescente.
Selezione indice
In genere, Spanner seleziona l'indice più efficiente per una query
utilizzando la modellazione
basata sui costi. Tuttavia, il suggerimento FORCE_INDEX
indica esplicitamente
Spanner per usare un indice di ricerca specifico. Ad esempio,
seguente mostra come forzare Spanner a utilizzare AlbumsIndex
:
SELECT AlbumId
FROM Albums @{FORCE_INDEX=AlbumsIndex}
WHERE SEARCH(AlbumTitle_Tokens, @p1)
Se l'indice di ricerca specificato non è idoneo, non va a buon fine, anche se sono presenti altri indici di ricerca idonei.
Snippet nei risultati di ricerca
Uno snippet è un testo estratto da una determinata stringa che offre agli utenti un di cosa contiene un risultato di ricerca e perché il risultato è pertinenti alla loro query.
Ad esempio, Gmail utilizza gli snippet per indicare la parte di un'email che corrisponde alla query di ricerca:
Fare in modo che il database generi uno snippet 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 dal server.
La funzione SNIPPET
crea lo snippet. Restituisce la parte pertinente di
il valore della stringa originale insieme alle posizioni dei caratteri da evidenziare. La
Il cliente può scegliere in che modo 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, nel seguente modo viene utilizzato SNIPPET
per recuperare 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 suddividere in pagine i risultati di ricerca.
- Scopri come combinare query full-text e non di testo.
- Scopri come cercare in più colonne.