Auf dieser Seite wird beschrieben, wie Sie Suchergebnisse für Volltextsuchen in Spanner einstufen.
Spanner unterstützt die Berechnung einer Aktualitätspunktzahl, die einen Baustein für die Erstellung komplexer Rankingfunktionen darstellt. Mit diesen Punktzahlen wird die Relevanz eines Ergebnisses für eine Abfrage anhand der Häufigkeit des Suchbegriffs und anderer anpassbarer Optionen berechnet.
Im folgenden Beispiel wird gezeigt, wie Sie mit der
SCORE
Funktion eine Suche mit Ranking durchführen:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY SCORE(AlbumTitle_Tokens, "fifth symphony") DESC
PostgreSQL
In diesem Beispiel wird spanner.search
mit
spanner.score verwendet.
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'fifth symphony')
ORDER BY spanner.score(albumtitle_tokens, 'fifth symphony') DESC
Suchbegriffe mit der Funktion SCORE bewerten
Die SCORE
Funktion berechnet eine Punktzahl für jeden Suchbegriff und kombiniert dann die Punktzahlen. Die
Punktzahl pro Begriff basiert ungefähr auf der Begriffshäufigkeit und der inversen Dokumenthäufigkeit
(TF/IDF). Die Punktzahl ist eine Komponente der endgültigen Reihenfolge für einen Eintrag. Die Abfrage kombiniert sie mit anderen Signalen, z. B. der Aktualität, die die Aktualitätspunktzahl beeinflusst.
In der aktuellen Implementierung ist der IDF-Teil von TF/IDF nur verfügbar, wenn
enhance_query=>true verwendet wird. Dabei wird die relative Häufigkeit von Wörtern anhand des gesamten Web-Korpus berechnet, das von der Google Suche verwendet wird, und nicht anhand eines bestimmten Suchindex. Wenn die Abfrageverbesserung nicht aktiviert ist, wird bei der Bewertung nur die Komponente der Begriffshäufigkeit (TF) verwendet (d. h., der IDF-Begriff wird auf 1 gesetzt).
Die Funktion SCORE gibt Werte zurück, die als Relevanzpunktzahlen dienen, mit denen Spanner eine Sortierreihenfolge festlegt. Sie haben keine eigenständige Bedeutung. Je höher die Punktzahl, desto besser passt sie zur Abfrage.
Normalerweise sind Argumente wie query und enhance_query in den Funktionen
SEARCH und SCORE gleich, um die Konsistenz beim Abrufen und Ranking zu gewährleisten.
Die empfohlene Vorgehensweise besteht darin, diese Argumente mit
Abfrageparametern
anstelle von String-Literalen zu verwenden und dieselben Abfrageparameter in den
SEARCH und SCORE Funktionen anzugeben.
Mehrere Spalten bewerten
Spanner verwendet die Funktion SCORE, um jedes Feld einzeln zu bewerten. Die Abfrage kombiniert dann diese einzelnen Punktzahlen. Eine gängige Methode besteht darin, die einzelnen Punktzahlen zu addieren und sie dann entsprechend den vom Nutzer angegebenen Feldgewichtungen zu erhöhen (die mithilfe von SQL-Abfrageparametern angegeben werden).
Die folgende Abfrage kombiniert beispielsweise die Ausgabe von zwei SCORE-Funktionen:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, @p1) OR SEARCH(Studio_Tokens, @p2)
ORDER BY SCORE(Title_Tokens, @p1) * @titleweight + SCORE(Studio_Tokens, @p2) * @studioweight
LIMIT 25
PostgreSQL
In diesem Beispiel werden die Suchparameter $1 und $2 verwendet, die an „fifth symphony“ bzw. „blue note“ gebunden sind.
SELECT albumid
FROM albums
WHERE spanner.search(title_tokens, $1) OR spanner.search(studio_tokens, $2)
ORDER BY spanner.score(title_tokens, $1) * $titleweight
+ spanner.score(studio_tokens, $2) * $studioweight
LIMIT 25
Im folgenden Beispiel werden zwei Boost-Parameter hinzugefügt:
- Aktualität (
FreshnessBoost) erhöht die Punktzahl mit(1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30). - Popularität(
PopularityBoost) erhöht die Punktzahl, indem sie mit dem Faktor(1 + IF(HasGrammy, @grammyweight, 0)multipliziert wird.
Zur besseren Lesbarkeit wird in der Abfrage der Operator WITH verwendet.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, @p1) OR 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
In diesem Beispiel werden die Abfrageparameter $1, $2, $3, $4, $5 und $6 verwendet, die an die für titlequery, studioquery, titleweight, studioweight, grammyweight und freshnessweight angegebenen Werte gebunden sind.
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) OR 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
kann auch sowohl bei der Suche als auch bei der Bewertung verwendet werden, um Abfragen gegebenenfalls zu vereinfachen.
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
In diesem Beispiel wird
spanner.tokenlist_concat verwendet.
Der Abfrageparameter $1 ist an „blue note“ gebunden.
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
Übereinstimmungen mit der Abfragereihenfolge verbessern
Spanner wendet einen multiplikativen Boost auf die Ausgabe der Funktion SCORE für Werte an, die die Suchbegriffe in derselben Reihenfolge enthalten, in der sie in der Abfrage vorkommen. Es gibt zwei Versionen dieses Boosts: teilweise Übereinstimmung und genaue Übereinstimmung. Ein Boost für teilweise Übereinstimmung wird angewendet, wenn:
- die
TOKENLISTalle ursprünglichen Begriffe in der Abfrage enthält. - die Tokens nebeneinander und in derselben Reihenfolge wie in der Abfrage vorkommen.
Für Konjunktionen, Negationen und Wortgruppen gelten bestimmte Sonderregeln:
- Eine Abfrage mit einer Negation kann keinen Boost für teilweise Übereinstimmung erhalten.
- Eine Abfrage mit einer Konjunktion erhält einen Boost, wenn ein Teil der Konjunktion an den entsprechenden Stellen vorkommt.
- Eine Abfrage mit einer Wortgruppe erhält einen Boost, wenn die Wortgruppe in der
TOKENLISTvorkommt und der Begriff links von der Wortgruppe in der Abfrage links von der Wortgruppe in derTOKENLISTvorkommt. Das Gleiche gilt für den Begriff rechts von der Wortgruppe.
Spanner wendet einen Boost für genaue Übereinstimmung an, wenn alle vorherigen Regeln zutreffen und die ersten und letzten Tokens in der Abfrage die ersten und letzten Tokens im Dokument sind.
Beispieldokument: Bridge Over Troubled Water
| Abfrage | Boost angewendet |
|---|---|
| Bridge Troubled | kein Boost |
| Bridge Over - other water | kein Boost |
| Bridge (Over OR Troubled) Water | kein Boost |
| Bridge Over | teilweiser Boost |
| Bridge Over (Troubled OR Water) | teilweiser Boost |
| Bridge Over Troubled Water | genauer Boost |
| Bridge "Over Troubled" Water | genauer Boost |
| Bridge ("Over Troubled" OR missingterm) Water | genauer Boost |
Scorer-Versionen
Der Scorer-Algorithmus wird regelmäßig aktualisiert. Jede Version enthält eine Reihe von Verbesserungen des Scoring-Algorithmus. Eine detaillierte Liste der Unterschiede zwischen den Versionen finden Sie unter Scorer-Versionen.
Sie können die Standardversion des Scorers für Ihre Datenbank festlegen oder eine Version für eine bestimmte Abfrage angeben.
Standardversion des Scorers für die Datenbank festlegen
Sie können die Standardversion des Scorer-Algorithmus für Ihre Datenbank festlegen. Diese Option bestimmt, welche Version des Scoring-Algorithmus von Spanner verwendet wird, wenn die Funktion SCORE ohne eine explizite Option version aufgerufen wird.
GoogleSQL
Legen Sie die Datenbankoption score_version fest:
ALTER DATABASE database_name SET OPTIONS (score_version = 2)
PostgreSQL
Legen Sie die Datenbankoption spanner.score_version fest:
ALTER DATABASE database_name SET "spanner.score_version" = 2
Gültige Werte für die Datenbankoption sind 1 oder 2. Wenn der Parameter version in einer Anfrage vorhanden ist, wird die Standardversion der Datenbank überschrieben.
Scorer-Version pro Abfrage überschreiben
Sie können die Standardversion des Scorers für eine bestimmte Abfrage mit dem Parameter version im Argument options der Funktion SCORE überschreiben. Wenn in einer Abfrage eine Scorer-Version definiert ist, wird die Standardversion der Datenbank überschrieben.
Im folgenden Beispiel wird die Standardversion des Scorers überschrieben, indem version im Parameter options angegeben wird:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, @query)
ORDER BY SCORE(
AlbumTitle_Tokens,
@query,
options=>JSON '{"version": 2}'
) DESC
PostgreSQL
In diesem Beispiel wird der Abfrageparameter $1 verwendet, der an den Abfragestring gebunden ist.
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, $1)
ORDER BY spanner.score(
albumtitle_tokens,
$1,
options => '{"version": 2}'::jsonb
) DESC
Abruftiefe begrenzen
Suchindizes enthalten oft Millionen von Dokumenten. Bei Abfragen, bei denen die Prädikate eine geringe Selektivität aufweisen, ist es unpraktisch, alle Ergebnisse zu bewerten. Bewertungsabfragen haben in der Regel zwei Limits:
- Limit für die Abruftiefe: die maximale Anzahl der zu bewertenden Zeilen.
- Limit für die Größe des Ergebnissatzes: die maximale Anzahl der Zeilen, die von der Abfrage zurückgegeben werden sollen (in der Regel die Seitengröße).
Abfragen können die Abruftiefe mit SQL-Unterabfragen begrenzen:
GoogleSQL
SELECT AlbumId
FROM
(
SELECT AlbumId, SCORE(Title_Tokens, @p1) AS score
FROM Albums
WHERE SEARCH(Title_Tokens, @p1)
ORDER BY ReleaseTimestamp DESC
LIMIT @retrieval_limit
)
ORDER BY score DESC
LIMIT @page_size
PostgreSQL
In diesem Beispiel werden die Abfrageparameter $1, $2 und $3 verwendet, die an die für title_query, retrieval_limit und page_size angegebenen Werte gebunden sind.
SELECT albumid
FROM
(
SELECT albumid, spanner.score(title_tokens, $1) AS score
FROM albums
WHERE spanner.search(title_tokens, $1)
ORDER BY releasetimestamp DESC
LIMIT $2
) AS subquery
ORDER BY score DESC
LIMIT $3
Das funktioniert besonders gut, wenn Spanner das wichtigste Ranking-Signal verwendet, um den Index zu sortieren.
Nächste Schritte
- Weitere Informationen zu Volltextsuchanfragen.
- Informationen zum Durchführen einer Teilstringsuche.
- Informationen zum Paginieren von Suchergebnissen
- Volltext- und Nicht-Text-Suchanfragen kombinieren
- Mehrere Spalten durchsuchen