Questa pagina descrive come classificare i risultati di ricerca per le ricerche full-text in Spanner.
Spanner supporta il calcolo di un punteggio di attualità, che fornisce un componente di base per la creazione di funzioni di ranking sofisticate. Questi punteggi calcolano la pertinenza di un risultato per una query, in base alla frequenza del termine di query e ad altre opzioni personalizzabili.
L'esempio seguente mostra come eseguire una ricerca classificata utilizzando la funzione SCORE:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY SCORE(AlbumTitle_Tokens, "fifth symphony") DESC
PostgreSQL
Questo esempio utilizza spanner.search
con
spanner.score.
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'fifth symphony')
ORDER BY spanner.score(albumtitle_tokens, 'fifth symphony') DESC
Assegna un punteggio ai termini di query con la funzione SCORE
La funzione SCORE
calcola un punteggio per ogni termine di ricerca e poi li combina. Il punteggio per termine si basa approssimativamente sulla frequenza del termine/frequenza inversa del documento
(TF/IDF). Il punteggio è un
componente dell'ordinamento finale di un record. La query lo combina con altri
segnali, ad esempio la freschezza che modula il punteggio di attualità.
Nell'implementazione attuale, la parte IDF di TF/IDF è disponibile solo quando viene utilizzato enhance_query=>true. Calcola la frequenza relativa delle parole
in base al corpus web completo utilizzato dalla Ricerca Google, anziché a un
indice di ricerca specifico. Se il miglioramento delle query correlate non è attivato, il punteggio
utilizza solo il componente della frequenza del termine (TF), ovvero il termine IDF è impostato su 1.
La funzione SCORE restituisce valori che fungono da punteggi di pertinenza che
Spanner utilizza per stabilire un ordinamento. Non hanno un significato autonomo. Più alto è il punteggio, migliore è la corrispondenza con la query.
Di solito, argomenti come query e enhance_query sono gli stessi per le funzioni SEARCH e SCORE per garantire coerenza nel recupero e nel ranking.
Il modo consigliato per farlo è utilizzare questi argomenti con i
parametri della query
anziché i valori letterali stringa e specificare gli stessparametri di ricercary nelle
funzioni SEARCH e SCORE.
Assegnare un punteggio a più colonne
Spanner utilizza la funzione SCORE per assegnare un punteggio a ogni campo
singolarmente. La query combina quindi questi singoli punteggi. Un modo comune per farlo è sommare i singoli punteggi e poi aumentarli in base ai pesi dei campi forniti dall'utente (che vengono forniti utilizzando i parametri della query SQL).
Ad esempio, la seguente query combina l'output di due funzioni SCORE:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, @p1) AND SEARCH(Studio_Tokens, @p2)
ORDER BY SCORE(Title_Tokens, @p1) * @titleweight + SCORE(Studio_Tokens, @p2) * @studioweight
LIMIT 25
PostgreSQL
Questo esempio utilizza parametri di ricerca $1 e $2, associati rispettivamente a
"quinta sinfonia" e "blue note".
SELECT albumid
FROM albums
WHERE spanner.search(title_tokens, $1) AND spanner.search(studio_tokens, $2)
ORDER BY spanner.score(title_tokens, $1) * $titleweight
+ spanner.score(studio_tokens, $2) * $studioweight
LIMIT 25
L'esempio seguente aggiunge due parametri di boost:
- L'aggiornamento (
FreshnessBoost) aumenta il punteggio di(1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30) - La popolarità(
PopularityBoost) aumenta il punteggio moltiplicandolo per il fattore(1 + IF(HasGrammy, @grammyweight, 0).
Per una maggiore leggibilità, la query utilizza l'operatore WITH.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, @p1) AND SEARCH(Studio_Tokens, @p2)
ORDER BY WITH(
TitleScore AS SCORE(Title_Tokens, @p1) * @titleweight,
StudioScore AS SCORE(Studio_Tokens, @p2) * @studioweight,
DaysOld AS (UNIX_MICROS(CURRENT_TIMESTAMP()) - ReleaseTimestamp) / 8.64e+10,
FreshnessBoost AS (1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30),
PopularityBoost AS (1 + IF(HasGrammy, @grammyweight, 0)),
(TitleScore + StudioScore) * FreshnessBoost * PopularityBoost)
LIMIT 25
PostgreSQL
Questo esempio utilizza parametri di ricerca $1, $2, $3, $4, $5 e $6
che sono associati ai valori specificati per titlequery, studioquery,
titleweight, studioweight, grammyweight e freshnessweight,
rispettivamente.
SELECT albumid
FROM
(
SELECT
albumid,
spanner.score(title_tokens, $1) * $3 AS titlescore,
spanner.score(studio_tokens, $2) * $4 AS studioscore,
(extract(epoch FROM current_timestamp) * 10e+6 - releasetimestamp) / 8.64e+10 AS daysold,
(1 + CASE WHEN hasgrammy THEN $5 ELSE 0 END) AS popularityboost
FROM albums
WHERE spanner.search(title_tokens, $1) AND spanner.search(studio_tokens, $2)
) AS subquery
ORDER BY (subquery.TitleScore + subquery.studioscore)
* (1 + $6 * greatest(0, 30 - subquery.daysold) / 30) * subquery.popularityboost
LIMIT 25
TOKENLIST_CONCAT
possono essere utilizzati anche nella ricerca e nell'assegnazione del punteggio per semplificare le query quando
opportuno.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens]), @p)
ORDER BY SCORE(TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens]), @p)
LIMIT 25
PostgreSQL
Questo esempio utilizza
spanner.tokenlist_concat.
Il parametro di ricerca $1 è associato a "blue note".
SELECT albumid
FROM albums
WHERE spanner.search(spanner.tokenlist_concat(ARRAY[title_tokens, studio_tokens]), $1)
ORDER BY spanner.score(spanner.tokenlist_concat(ARRAY[title_tokens, studio_tokens]), $1)
LIMIT 25
Aumentare le corrispondenze dell'ordine di query
Spanner applica un incremento moltiplicativo all'output della funzione
SCORE per i valori che contengono i termini di query nello stesso ordine in cui
appaiono nella query. Esistono due versioni di questo boost: corrispondenza parziale
e corrispondenza esatta. Viene applicato un incremento della corrispondenza parziale quando:
TOKENLISTcontiene tutti i termini originali della query.- I token sono adiacenti e nello stesso ordine in cui appaiono nella query.
Esistono regole speciali per congiunzioni, negazioni e frasi:
- Una query con una negazione non può ricevere un aumento della corrispondenza parziale.
- Una query con una congiunzione riceve un boost se parte della congiunzione viene visualizzata nelle posizioni appropriate.
- Una query con una frase riceve un boost se la frase viene visualizzata nel
TOKENLISTe il termine a sinistra della frase nella query viene visualizzato a sinistra della frase nelTOKENLISTe lo stesso vale per il termine a destra della frase.
Spanner applica un aumento della corrispondenza esatta quando tutte le regole precedenti sono vere e il primo e l'ultimo token nella query sono il primo e l'ultimo token nel documento.
Documento di esempio: Bridge Over Troubled Water
| Query | Potenziamento applicato |
|---|---|
| Bridge Troubled | nessun boost |
| Ponte sopra - altra acqua | nessun boost |
| Bridge (Over OR Troubled) Water | nessun boost |
| Bridge Over | incremento parziale |
| Bridge Over (Troubled OR Water) | incremento parziale |
| Bridge Over Troubled Water | aumento esatto |
| Ponte "Over Troubled" Water | aumento esatto |
| Ponte ("Over Troubled" OR missingterm) Water | aumento esatto |
Limitare la profondità di recupero
Gli indici di ricerca spesso contengono milioni di documenti. Per le query in cui i predicati hanno una bassa selettività, è poco pratico classificare tutti i risultati. Le query di valutazione di solito hanno due limiti:
- Limite di profondità di recupero: il numero massimo di righe da valutare.
- Limite di dimensioni del set di risultati: il numero massimo di righe che la query deve restituire (in genere le dimensioni della pagina).
Le query possono limitare la profondità di recupero con le sottoquery SQL:
GoogleSQL
SELECT *
FROM (
SELECT AlbumId, Title_Tokens
FROM Albums
WHERE SEARCH(Title_Tokens, @p1)
ORDER BY ReleaseTimestamp DESC
LIMIT @retrieval_limit
)
ORDER BY SCORE(Title_Tokens, @p1)
LIMIT @page_size
PostgreSQL
Questo esempio utilizza i parametri di ricerca $1, $2 e $3 associati ai valori specificati per title_query, retrieval_limit e page_size, rispettivamente.
SELECT *
FROM (
SELECT albumid, title_tokens
FROM albums
WHERE spanner.search(title_tokens, $1)
ORDER BY releasetimestamp DESC
LIMIT $2
) AS subquery
ORDER BY spanner.score(subquery.title_tokens, $1)
LIMIT $3
Questo funziona particolarmente bene se Spanner utilizza l'indicatore di ranking più importante per ordinare l'indice.
Passaggi successivi
- Scopri di più sulle query di ricerca full-text.
- Scopri come eseguire una ricerca di sottostringa.
- Scopri come impaginare i risultati di ricerca.
- Scopri come combinare query di testo e non di testo.
- Scopri come cercare in più colonne.