このページでは、全文データと非テキストデータを組み合わせて検索する方法について説明します。
全文検索と非テキスト検索を組み合わせて行う
検索インデックスは、全文列、完全一致列、数値列をサポートします。複数列検索クエリと同様に、WHERE
句でテキスト条件と非テキスト条件を組み合わせることができます。クエリ オプティマイザは、検索インデックスを使用してテキスト以外の述語を最適化しようとします。それが不可能な場合、Spanner は検索インデックスに一致するすべての行に対して条件を評価します。検索インデックスに保存されていない参照列は、ベーステーブルからフェッチされます。
たとえば、次の例をご覧ください。
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
Title STRING(MAX),
Rating FLOAT64,
Genres ARRAY<STRING(MAX)>,
Likes INT64,
Cover BYTES(MAX),
Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN,
Genres_Tokens TOKENLIST AS (TOKEN(Genres)) HIDDEN
) PRIMARY KEY(AlbumId);
CREATE SEARCH INDEX AlbumsIndex
ON Albums(Title_Tokens, Rating_Tokens, Genres_Tokens)
STORING Likes;
このテーブルに対するクエリの動作は次のとおりです。
Rating
とGenres
は検索インデックスに含まれます。Spanner は、検索インデックスの投稿リストを使用して条件を高速化します。SELECT Album FROM Albums WHERE Rating > 4 AND ARRAY_INCLUDES_ANY(Genres, ['jazz'])
クエリでは、完全テキスト述語と非テキスト述語の組み合わせなど、任意の方法で結合、除外、否定を組み合わせることができます。このクエリは検索インデックスによって完全に高速化されます。
SELECT Album FROM Albums WHERE (SEARCH(Title_Tokens, 'car') OR Rating > 4) AND NOT ARRAY_INCLUDES_ANY(Genres, ['jazz'])
Likes
はインデックスに保存されますが、スキーマは Spanner に有効な値のトークン インデックスを作成するようリクエストしません。このため、Title
に対する全文述語とRating
に対する非テキスト述語は高速化されますが、Likes
に対する述語は高速化されません。Spanner では、Title
に「car」というキーワードが含まれ、評価が 4 より大きいすべてのドキュメントがクエリによって取得され、高評価が 1,000 件未満のドキュメントが除外されます。ほとんどのアルバムのタイトルに「car」という単語が含まれ、ほとんどのアルバムの評価が 5 点であるものの、高評価(1,000 件)のアルバムはほとんどない場合、このクエリは多くのリソースを使用します。そのような場合は、Rating
と同様にLikes
にインデックスを付けると、リソースを節約できます。SELECT Album FROM Albums WHERE SEARCH(Title_Tokens, 'car') AND Rating > 4 AND Likes >= 1000
Cover
はインデックスに保存されません。次のクエリは、AlbumsIndex
とAlbums
のバック結合を行い、一致するすべてのアルバムのCover
を取得します。SELECT AlbumId, Cover FROM Albums WHERE SEARCH(Title_Tokens, 'car') AND Rating > 4
次のステップ
- 全文検索クエリについて学習する。
- 検索結果をランク付けする方法を確認する。
- 部分文字列検索を行う方法を学習する。
- 検索結果をページ分けする方法を学習する。
- 複数の列を検索する方法について学ぶ。