TOKENLISTs kombinieren

Auf dieser Seite wird beschrieben, wie Sie TOKENLISTs entweder in einem Suchindex beim Einrichten des Schemas oder in einer Suchanfrage bei einer Volltextsuche in Spanner.

TOKENLISTs in einem Suchindex kombinieren

Manchmal muss Ihre Anwendung in einzelnen Feldern suchen. In anderen Fällen muss die Anwendung in allen Feldern suchen. In einer Tabelle mit zwei Stringspalten kann Ihre Anwendung beispielsweise in beiden Spalten suchen, ohne zu unterscheiden, aus welcher Spalte die Übereinstimmungen stammen.

In Spanner gibt es zwei Möglichkeiten, dies zu erreichen:

  1. Wörter einzeln tokenisieren und die resultierenden TOKENLIST-Werte zusammenführen (empfohlen)
  2. Strings zusammenführen und das Ergebnis tokenisieren.

Beim zweiten Ansatz gibt es zwei Probleme:

  1. Wenn Sie Title oder Studio zusätzlich zu in einem kombinierten TOKENLIST indexiert, wird derselbe Text zweimal tokenisiert. Dadurch werden für Transaktionen mehr Ressourcen benötigt.
  2. Eine Wortgruppensuche umfasst beide Felder. Wenn @p beispielsweise auf "Blue Note" festgelegt ist, wird eine Zeile mit Title=„Big Blue Note“ und Studio=„Blue Note Studios“ gefunden.

Der erste Ansatz löst diese Probleme, da eine Wortgruppe nur mit einem Feld übereinstimmt Jedes Stringfeld wird nur einmal tokenisiert, wenn sowohl das individuelle als auch das kombinierte Feld TOKENLIST sind indexiert. Auch wenn jedes Stringfeld nur einmal tokenisiert wird, Die resultierenden TOKENLISTs werden separat im Index gespeichert.

Wörter separat tokenisieren und TOKENLIST-Werte verketten

Im folgenden Beispiel wird jedes Wort tokenisiert und die TOKENLIST verkettet Werte:

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Title STRING(MAX),
  Studio STRING(MAX),
  Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
  Studio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Studio)) HIDDEN,
  Combined_Tokens TOKENLIST AS (TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens])) HIDDEN,
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Combined_Tokens);

SELECT AlbumId FROM Albums WHERE SEARCH(Combined_Tokens, @p);

Die TOKENLIST-Konkatenierung kann auch vollständig auf Abfrageseite implementiert werden. Weitere Informationen finden Sie unter Abfrageseitige TOKENLIST-Konkatenierung.

TOKENLIST_CONCAT wird sowohl für Volltext- als auch substring sucht. Spanner lässt nicht zu, dass Sie Tokenisierungstypen wie TOKENIZE_FULLTEXT und TOKENIZE_SUBSTRING im selben TOKENLIST_CONCAT anrufen.

Die Definition von Textspalten TOKENLIST kann in nicht gespeicherten Spalten geändert werden um weitere Spalten hinzuzufügen. Dies ist nützlich, wenn Sie eine weitere in TOKENLIST_CONCAT. Wenn Sie den Ausdruck der generierten Spalte ändern, werden vorhandene Zeilen im Index nicht aufgefüllt.

Strings zusammenführen und das Ergebnis tokenisieren

Im folgenden Beispiel werden Strings zusammengefügt und das Ergebnis tokenisiert:

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Title STRING(MAX),
  Studio STRING(MAX),
  Combined_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title || " " || Studio)) HIDDEN,
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Combined_Tokens);

SELECT AlbumId FROM Albums WHERE SEARCH(Combined_Tokens, @p);

Abfrageseitige TOKENLIST-Konkatenierung

Der Nachteil bei der Indexierung der verketteten TOKENLIST besteht darin, dass sie Speicher- und Schreibkosten. Jedes Token wird jetzt zweimal auf dem Laufwerk gespeichert: einmal in einer Posting-Liste der ursprünglichen TOKENLIST und einmal in einer Posting-Liste der kombinierten TOKENLIST. Abfrageseitige Verkettung von TOKENLIST-Spalten diese Kosten werden vermieden, aber die Abfrage benötigt mehr Rechenressourcen.

Wenn Sie mehrere TOKENLIST-Werte verketten möchten, verwenden Sie die Funktion TOKENLIST_CONCAT in der Abfrage SEARCH. In diesem Abschnitt verwenden wir das folgende Beispielschema:

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Title STRING(MAX),
  Studio STRING(MAX),
  Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
  Studio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Studio)) HIDDEN,
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Title_Tokens, Studio_Tokens);

Die folgende Abfrage sucht nach Zeilen, die das Token „blau“ enthalten und „Notiz“ an einer beliebigen Stelle in den Spalten Title und Studio. Dazu gehören Zeilen, in denen sowohl „blau“ und „Notiz“ in der Spalte Title, „blue“ und „Notiz“ in der Studio-Spalte und „blau“ in der Spalte Title und in „Notiz“ in Studio oder umgekehrt.

SELECT AlbumId
FROM Albums
WHERE SEARCH(TOKENLIST_CONCAT([AlbumTitle_Tokens, Studio_Tokens]), 'blue note')

Die Verkettung von TOKENLIST auf Schreib- und Abfrageseite führt zu identischen Ergebnissen. Die Wahl zwischen den beiden Optionen ist ein Kompromiss zwischen Laufwerks- und Abfragekosten.

Alternativ kann eine Anwendung in mehreren TOKENLIST-Spalten suchen und OR zusammen mit der Funktion SEARCH verwenden:

SEARCH(AlbumTitle_Tokens, 'Blue Note') OR SEARCH(Studio_Tokens, 'Blue Note')

Dies hat jedoch eine andere Semantik. Es stimmt nicht mit Alben überein, in denen AlbumTitle_Tokens enthält „blau“, aber nicht „Notiz“ und Studio_Tokens hat „note“, aber nicht „blue“.

Nächste Schritte