全文クエリと非テキストクエリを組み合わせる

このページでは、全文データと非テキストデータを組み合わせて検索する方法について説明します。

検索インデックスは、全文列、完全一致列、数値列をサポートします。複数列検索クエリと同様に、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;

このテーブルに対するクエリの動作は次のとおりです。

  • RatingGenres は検索インデックスに含まれます。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 はインデックスに保存されません。次のクエリは、AlbumsIndexAlbumsバック結合を行い、一致するすべてのアルバムの Cover を取得します。

    SELECT AlbumId, Cover
    FROM Albums
    WHERE SEARCH(Title_Tokens, 'car')
      AND Rating > 4
    

次のステップ