Questa pagina descrive come classificare i risultati di ricerca per le ricerche full-text in Spanner.
Spanner supporta il calcolo di un punteggio di pertinenza, che fornisce un elemento costitutivo 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 della 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
Assegnare un punteggio ai termini di query con la funzione SCORE
La funzione SCORE
calcola un punteggio per ogni termine di query e poi li combina. Il
voto per termine si basa approssimativamente sulla frequenza del termine e sulla frequenza inversa del documento
(TF/IDF). Il punteggio è uno
componente dell'ordinamento finale di un record. La query la combina con altri indicatori, ad esempio l'aggiornamento che modula il punteggio di pertinenza.
Nell'implementazione attuale, la parte IDF di TF/IDF è disponibile solo se viene utilizzato
enhance_query=>true
. Calcola la frequenza relativa delle parole
in base all'intero corpus web utilizzato dalla Ricerca Google, anziché a
un indice di ricerca specifico. Se il miglioramento della query r non è attivato, il calcolo del punteggio utilizza solo il componente della frequenza dei termini (ovvero il termine IDF è impostato su 1).
La funzione SCORE
restituisce valori che fungono da punteggi di pertinenza utilizzati da Spanner per stabilire un ordine di ordinamento. Non hanno un significato autonomo. Più alto è il punteggio, maggiore è la corrispondenza con la query.
In genere, argomenti come query
e enhance_query
sono gli stessi per le funzioni SEARCH
e SCORE
per garantire la coerenza nel recupero e nel ranking.
Il modo consigliato per farlo è utilizzare questi argomenti con
parametri di query
anziché con stringhe letterali e specificare gli stessi parametri di query nelle
funzioni SEARCH
e SCORE
.
Assegnare un punteggio a più colonne
Spanner utilizza la funzione SCORE
per assegnare un punteggio a ciascun campo individualmente. 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 (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 i parametri di query $1
e $2
, associati rispettivamente a "quinta sinfonia" e "nota blu".
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 con(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 i parametri di query $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
può essere utilizzato anche nella ricerca e nel calcolo del punteggio per semplificare le query, se 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 query $1
è associato a "nota blu".
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
Migliorare le corrispondenze dell'ordine delle 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 potenziamento: corrispondenza parziale
e corrispondenza esatta. Un aumento della corrispondenza parziale viene applicato quando:
TOKENLIST
contiene tutti i termini originali della query.- I token sono adiacenti tra loro e nello stesso ordine in cui appaiono nella query.
Esistono alcune regole speciali per congiuntivi, negazioni e frasi:
- Una query con un'espressione di negazione non può ricevere un miglioramento della corrispondenza parziale.
- Una query con una congiunzione riceve un aumento se parte della congiunzione appare nelle posizioni appropriate.
- Una query con una frase riceve un aumento se la frase compare nel
TOKENLIST
e il termine a sinistra della frase nella query compare a sinistra della frase nelTOKENLIST
, e lo stesso vale per il termine a destra della frase.
Spanner applica un miglioramento della corrispondenza esatta quando tutte le regole precedenti sono vere e i token primo e ultimo della query sono i token primo e ultimo del documento.
Documento di esempio: Bridge Over Troubled Water
Query | Potenziamento applicato |
---|---|
Problemi con il ponte | nessun miglioramento |
Ponte sopra - altro corpo d'acqua | nessun miglioramento |
Ponte (sopra o con acque agitate) | nessun miglioramento |
Bridge Over | aumento parziale |
Ponte (acque agitate OPPURE acqua) | aumento parziale |
Bridge Over Troubled Water | aumento esatto |
Ponte "sopra acque agitate" | aumento esatto |
Ponte ("Over Troubled" OPPURE missingterm) Acqua | aumento esatto |
Limita la profondità di recupero
Gli indici di ricerca spesso contengono milioni di documenti. Per le query in cui i predicati hanno una bassa selettività, non è pratico assegnare un ranking a tutti i risultati. Le query di punteggio hanno in genere due limiti:
- Limite di profondità di recupero: il numero massimo di righe da valutare.
- Limite di dimensione 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 query $1
, $2
e $3
, associati rispettivamente ai valori specificati per title_query
, retrieval_limit
e page_size
.
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 il segnale di ranking più importante per ordinare l'indice.
Passaggi successivi
- Scopri di più sulle query di ricerca a testo intero.
- 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.