検索インデックスで複数の列を検索する

検索インデックスでは、複数のトークン化された列にインデックスを付けることができるため、これらの列に対するクエリを効率化できます。このページでは、全文検索の一種である複数の列を検索する方法について説明します。

検索インデックスの構造により、クエリに分散結合が不要になり、クエリのパフォーマンスが予測可能です。同じスプリットのベーステーブル行に対応するすべてのトークンのコロケーションによって、分散結合は回避されます。

たとえば、次のスキーマについて考えてみましょう。

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);

クエリで両方のフィールドを検索できるようになりました。

SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, "fifth symphony")
  AND SEARCH(Studio_Tokens, "Blue Note Studio")

Spanner は、WHERE 句の連結演算子、論理和演算子、否定演算子で複数列検索クエリをサポートしています。検索インデックスでは、次のタイプのクエリをすべて使用できます。

  • 結合: Title に「car」、Studio に「sun」という用語が含まれるドキュメントを検索します。

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(Title_Tokens, 'car') AND SEARCH(Studio_Tokens, 'sun')
    
  • 分離: Title に「car」という用語が含まれるか、Studio に「sun」という用語が含まれるドキュメントを検索します。

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(Title_Tokens, 'car') OR SEARCH(Studio_Tokens, 'sun')
    
  • 否定: Title に「car」という語句が含まれていないすべてのドキュメントを検索します。

    SELECT AlbumId
    FROM Albums
    WHERE NOT SEARCH(Title_Tokens, 'car')
    

    rquery 言語では、次のような検索を実行できます。

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(Title_Tokens, '-car')
    

    どちらの形式も、Title が NULL であるドキュメントをフィルタします。トークン化関数と検索関数は、NULL 入力で NULL を返すように定義されています。SQL は NOT NULL を NULL として定義します。

また、同じ TOKENLIST 列を複数回参照することもできます。

SELECT AlbumId
FROM Albums
WHERE (SEARCH(Title_Tokens, 'car') OR SEARCH(Studio_Tokens, 'sun'))
  AND (SEARCH(Title_Tokens, 'guy') OR SEARCH(Studio_Tokens, electric))

同じ列内の複数の用語を検索するには、rquery 言語または SQL を使用します。パラメータ化されたクエリに対して効率的なクエリキャッシュが使用されるため、rquery を使用することをおすすめします。クエリ キャッシュのヒット率が優れていることとは別に、rquery 言語と SQL 言語のレイテンシとパフォーマンスは変わりません。

SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, 'car OR guy')

SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, 'car') OR SEARCH(Title_Tokens, 'guy')

検索インデックスで高速化されたテキスト以外の条件は、全文検索関数で使用できます。

次のステップ