Suchergebnisse einstufen

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:

  1. die TOKENLIST alle ursprünglichen Begriffe in der Abfrage enthält.
  2. 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 TOKENLIST vorkommt und der Begriff links von der Wortgruppe in der Abfrage links von der Wortgruppe in der TOKENLIST vorkommt. 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:

  1. Limit für die Abruftiefe: die maximale Anzahl der zu bewertenden Zeilen.
  2. 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