Suchergebnisse einstufen

Auf dieser Seite wird beschrieben, wie Sie Suchergebnisse für die Volltextsuche in Spanner bewerten.

Spanner unterstützt die Berechnung eines Aktualitätswerts, der einen Baustein für die Erstellung komplexer Rankingfunktionen darstellt. Diese Werte berechnen die Relevanz eines Ergebnisses für eine Abfrage basierend auf der Häufigkeit des Abfragebegriffs und anderen anpassbaren Optionen.

Im folgenden Beispiel wird gezeigt, wie Sie mit der Funktion SCORE 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 Funktion SCORE berechnet für jeden Suchbegriff einen Wert und kombiniert die Werte dann. Die Punktzahl pro Begriff basiert ungefähr auf der Begriffshäufigkeit – inverse 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 den Aktualitätswert moduliert.

In der aktuellen Implementierung ist der IDF-Teil von TF/IDF nur verfügbar, wenn enhance_query=>true verwendet wird. Die relative Häufigkeit von Wörtern wird anhand des gesamten Webkorpus berechnet, der von der Google Suche verwendet wird, und nicht anhand eines bestimmten Suchindex. Wenn die rquery-Optimierung nicht aktiviert ist, wird für die Bewertung nur die Term Frequency (TF) verwendet (d. h. der IDF-Term wird auf 1 gesetzt).

Die Funktion SCORE gibt Werte zurück, die als Relevanzwerte dienen, mit denen Spanner eine Sortierreihenfolge festlegt. Sie haben keine eigenständige Bedeutung. Je höher der Wert, desto besser passt es zur Abfrage.

In der Regel sind Argumente wie query und enhance_query in den Funktionen SEARCH und SCORE identisch, um Konsistenz beim Abrufen und Ranking zu gewährleisten.

Die empfohlene Methode besteht darin, diese Argumente mit Abfrageparametern anstelle von Stringliteralen zu verwenden und dieselben Abfrageparameter in den Funktionen SEARCH und SCORE anzugeben.

Mehrere Spalten bewerten

Spanner verwendet die Funktion SCORE, um jedes Feld einzeln zu bewerten. In der Abfrage werden diese einzelnen Werte dann kombiniert. Eine gängige Methode hierfür ist, die einzelnen Punktzahlen zu addieren und dann entsprechend den vom Nutzer angegebenen Feldgewichtungen (die über SQL-Abfrageparameter bereitgestellt werden) zu erhöhen.

In der folgenden Abfrage wird beispielsweise die Ausgabe von zwei SCORE-Funktionen kombiniert:

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 Parameter für die Hochstufung hinzugefügt:

  • Die Aktualität (FreshnessBoost) erhöht die Punktzahl um (1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30).
  • Die Beliebtheit(PopularityBoost) erhöht den Wert, indem sie ihn mit dem Faktor (1 + IF(HasGrammy, @grammyweight, 0) multipliziert.

Aus Gründen der 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 für die Suche als auch für die Bewertung verwendet werden, um Abfragen bei Bedarf 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 Suchparameter $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 Reihenfolge der Suchbegriffe hochstufen

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: Teilübereinstimmung und genaue Übereinstimmung. Ein Boost für teilweise Übereinstimmung wird in folgenden Fällen angewendet:

  1. TOKENLIST enthält alle ursprünglichen Begriffe in der Abfrage.
  2. Die Tokens befinden sich nebeneinander und in derselben Reihenfolge wie in der Abfrage.

Für Konjunktionen, Negationen und Wortgruppen gelten bestimmte Sonderregeln:

  • Eine Abfrage mit einer Negation kann keine Boost-Anpassung für teilweise Übereinstimmungen erhalten.
  • Eine Abfrage mit einer Konjunktion wird optimiert, wenn ein Teil der Konjunktion an den entsprechenden Stellen erscheint.
  • Eine Abfrage mit einer Wortgruppe wird optimiert, wenn die Wortgruppe im TOKENLIST vorkommt und der Begriff links von der Wortgruppe in der Abfrage links von der Wortgruppe im TOKENLIST vorkommt. Dasselbe gilt für den Begriff rechts von der Wortgruppe.

Cloud Spanner wendet eine Boost-Regel für genaue Übereinstimmungen an, wenn alle vorherigen Regeln erfüllt sind 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
Brücke über – anderes Gewässer kein Boost
Bridge (Over OR Troubled) Water kein Boost
Brücke über Teilweise Erhöhung
Bridge Over (Troubled OR Water) Teilweise Erhöhung
Bridge Over Troubled Water Exakter Boost
Bridge Over Troubled Water Exakter Boost
Bridge ("Over Troubled" OR missingterm) Water exakter Boost

Scorer-Versionen

Der Bewertungsalgorithmus wird regelmäßig aktualisiert. Jede Version enthält eine Reihe von Verbesserungen am Bewertungsalgorithmus. Eine detaillierte Liste der Unterschiede zwischen den Versionen finden Sie unter Scorer-Versionen.

Sie können die Standard-Scorer-Version für Ihre Datenbank festlegen oder eine Version für eine bestimmte Abfrage angeben.

Wenn Sie keine Scorer-Version für Ihre Datenbank oder Abfrage angeben, wird die Standard-Scorer-Version automatisch aktualisiert, wenn eine neuere Version veröffentlicht wird.

Wenn Sie Suchergebnisse mit Ranking paginieren, können Änderungen der Scorer-Version dazu führen, dass Zeilen auf Seiten übersprungen oder wiederholt werden. Weitere Informationen finden Sie unter Suchergebnisse mit Ranking paginieren.

Standard-Scorer-Version der Datenbank festlegen

Sie können die Standardversion des Scorer-Algorithmus für Ihre Datenbank festlegen. Diese Option bestimmt, welche Version des Bewertungsalgorithmus von Spanner verwendet wird, wenn die Funktion SCORE ohne explizite version-Bewertungsoption 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

Die gültigen 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 Standard-Scorer-Version 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

Suchindexe enthalten oft Millionen von Dokumenten. Bei Abfragen, bei denen die Prädikate eine geringe Selektivität haben, ist es unpraktisch, alle Ergebnisse zu bewerten. Für Scoring-Abfragen gelten in der Regel zwei Limits:

  1. Retrieval depth limit: die maximale Anzahl der zu bewertenden Zeilen.
  2. Größenlimit für Ergebnissatz: Die maximale Anzahl von Zeilen, die die Abfrage zurückgeben soll (normalerweise 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 Suchparameter $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 Cloud Spanner das wichtigste Ranking-Signal zum Sortieren des Index verwendet.

Nächste Schritte