すべてのプロダクト
Search
ドキュメントセンター

AnalyticDB:BM25 パフォーマンス専有型全文検索

最終更新日:Feb 20, 2025

このトピックでは、pgsearch 拡張機能の概要と、拡張機能をインストール、アンインストール、および使用して全文検索を実行する方法について説明します。

概要

pgsearch 拡張機能は、高性能全文検索エンジンである Tantivy に基づいて構築された Best Matching 25(BM25)インデックスの作成と管理に役立ちます。 BM25 アルゴリズムは、Elasticsearch などの検索エンジンで優先的に使用され、行内の用語の出現回数と行全体の用語の希少性に基づいて行のスコア付けとランク付けを行います。 BM25 アルゴリズムは、多数の行からキーワードまたはフレーズを検索する場合に適しています。 BM25 インデックスを使用して AnalyticDB for PostgreSQL テーブルで全文検索を実行し、BM25 アルゴリズムを使用して関連性スコアに基づいて正確な検索結果を照合できます。

インストールとアンインストール

pgsearch 拡張機能は、GUI ベースのインストールをサポートしていません。 pgsearch 拡張機能をインストールするには、チケットを送信する 必要があります。拡張機能をインストールした後、AnalyticDB for PostgreSQL インスタンスを再起動する必要があります。 pgsearch 拡張機能をアンインストールするには、チケットを送信してください。

テストテーブル

この例では、数十行のテストテーブルを使用します。 pgsearch.create_test_table() 関数を呼び出して、テストテーブルを作成できます。

CALL pgsearch.create_test_table(table_name => 'mock_items', schema_name => 'public');

テーブルスキーマ

CREATE TABLE mock_items (
 description TEXT,
 rating INTEGER CHECK (
 rating BETWEEN 1
 AND 5
 ),
 category VARCHAR(255),
 in_stock BOOLEAN,
 metadata JSONB,
 created_at TIMESTAMP,
 last_updated_date DATE,
 latest_available_time TIME
);

インデックス管理

重要

インデックスの作成と削除はロールバックできません。

インデックスを作成する

pgsearch.create_bm25() 関数を呼び出して、BM25 インデックスを作成できます。この関数を使用すると、複数のフィールドにインデックスを作成し、各フィールドにインデックス構成を指定できます。複数のインデックスを作成すると、過剰なリソースが消費され、ユーザーエクスペリエンスに影響します。テーブルごとに BM25 インデックスを 1 つだけ作成することをお勧めします。

構文

CALL pgsearch.create_bm25(
  index_name => '<index_name>',
  table_name => '<table_name>',
  schema_name => '<schem_name>'
  text_fields => '<text_fields>|pgsearch.field()',
  numeric_fields => '<numeric_fields>|pgsearch.field()',
  boolean_fields => '<boolean_fields>|pgsearch.field()',
  json_fields => '<json_fields>|pgsearch.field()',
  datetime_fields => '<datetime_fields>|pgsearch.field()'
)

パラメーター

パラメーター

必須

サポートされているデータ型

説明

index_name

はい

STRING

インデックスの名前。

table_name

はい

STRING

インデックスを作成するテーブルの名前。

schema_name

いいえ

STRING

テーブルのスキーマ。デフォルトでは、現在のスキーマが使用されます。

text_fields

はい(少なくとも 1 つ)

  • VARCHAR

  • VARCHAR[]

  • TEXT

  • TEXT[]

インデックスを作成するテキストフィールドと、対応するインデックス構成。 JSON5 文字列を使用するか、pgsearch.field() 関数を呼び出すことによって、各フィールドのインデックス構成を指定します。

  • JSON5 文字列

    JSON5 文字列は、キーと値のペアで構成されます。キーをテーブル内のフィールドの名前に設定し、値をインデックス構成に設定します。サポートされているインデックス [設定項目]:

    • fast: フィールドにランダムにすばやくアクセスできるかどうかを指定します。この [設定項目] を使用すると、スコアリングとフィルタリングを高速化できます。デフォルト値: false。

    • fieldnorms: テキストフィールドの長さが保存されるかどうかを指定します。デフォルト値: true。 fieldnorms [設定項目] を true に設定した場合にのみ、BM25 スコアを計算できます。

    • tokenizer: トークナイザーと対応する構成(JSON5 形式)。詳細については、このトピックの「トークナイザー」セクションを参照してください。

    • record: インデックスに関する情報。デフォルト値: position。詳細については、このトピックの「レコード」セクションを参照してください。

  • pgsearch.field() 関数。

    pgsearch.field() 関数を呼び出して、特定のフィールドのインデックス構成を生成できます。複数のフィールドのインデックス構成を指定するには、複数の pgsearch.field() 関数を呼び出し、二重縦棒(||)を使用して関数を連結します。

    構文

    pgsearch.field(<name>, <fast>, <fieldnorms>, <record>, <expand_dots>, <tokenizer>)

    パラメーター

    • name: インデックスを作成するカラムの名前(テキスト型)。

    • fastfieldnormsrecordexpand_dotstokenizer パラメーターの詳細については、このテーブルの前の情報を参照してください。

重要

V7.2.1.0 以降の AnalyticDB for PostgreSQL インスタンスのみが pgsearch.field() 関数をサポートしています。 V7.2.1.0 以降の AnalyticDB for PostgreSQL インスタンスのインデックスを作成するには、pgsearch.field() 関数を呼び出す必要があります。そうしないと、jieba トークナイザーのカスタム単語分割辞書とストップワード辞書が有効になりません。

numeric_fields

  • INT2

  • INT2[]

  • INT4

  • INT4[]

  • INT8

  • INT8[]

  • OID

  • OID[]

  • XID

  • XID[]

  • FLOAT4

  • FLOAT4[]

  • FLOAT8

  • FLOAT8[]

  • NUMERIC

  • NUMERIC[]

インデックスを作成する数値フィールドと、対応するインデックス構成。 JSON5 文字列を使用するか、pgsearch.field() 関数を呼び出すことによって、各フィールドのインデックス構成を指定します。

  • JSON5 文字列

    JSON5 文字列は、キーと値のペアで構成されます。キーをテーブル内のフィールドの名前に設定し、値をインデックス構成に設定します。サポートされているインデックス [設定項目]:

    fast: フィールドにランダムにすばやくアクセスできるかどうかを指定します。この [設定項目] を使用すると、スコアリングとフィルタリングを高速化できます。デフォルト値: true。

  • pgsearch.field() 関数。

    pgsearch.field() 関数を呼び出して、特定のフィールドのインデックス構成を生成できます。複数のフィールドのインデックス構成を指定するには、複数の pgsearch.field() 関数を呼び出し、二重縦棒(||)を使用して関数を連結します。詳細については、このテーブルの前の情報を参照してください。

boolean_fields

  • BOOLEAN

  • BOOLEAN[]

インデックスを作成するブールフィールドと、対応するインデックス構成。

  • 使用する <boolean_fields>インデックスを構成します。

    サポートされているインデックス [設定項目]:

    fast: フィールドにランダムにすばやくアクセスできるかどうかを指定します。この [設定項目] を使用すると、スコアリングとフィルタリングを高速化できます。デフォルト値: true。

  • pgsearch.field() 関数。

    pgsearch.field() 関数を呼び出して、特定のフィールドのインデックス構成を生成できます。複数のフィールドのインデックス構成を指定するには、複数の pgsearch.field() 関数を呼び出し、二重縦棒(||)を使用して関数を連結します。詳細については、このテーブルの前の情報を参照してください。

json_fields

  • JSON

  • JSONB

インデックスを作成する JSON フィールドと、対応するインデックス構成。

  • JSON5 文字列

    JSON5 文字列は、キーと値のペアで構成されます。キーをテーブル内のフィールドの名前に設定し、値をインデックス構成に設定します。インデックスが作成されると、インデックスを使用して JSON 値内のネストされたテキストフィールドで検索を実行できます。サポートされているインデックス [設定項目]:

    • fast: フィールドにランダムにすばやくアクセスできるかどうかを指定します。この [設定項目] を使用すると、スコアリングとフィルタリングを高速化できます。デフォルト値: false。

    • expand_dots: ピリオド(.)を含む JSON キーを展開するかどうかを指定します。デフォルト値: true。たとえば、expand_dots [設定項目] を true に設定すると、{"metadata.color": "red"} は {"metadata": {"color": "red"}} としてインデックス付けされます。

    • tokenizer: トークナイザーと対応する構成。このパラメーターを en_stem に設定することをお勧めします。詳細については、このトピックの「トークナイザー」セクションを参照してください。

    • record: インデックスに関する情報。デフォルト値: position。詳細については、このトピックの「レコード」セクションを参照してください。

  • pgsearch.field() 関数。

    pgsearch.field() 関数を呼び出して、特定のフィールドのインデックス構成を生成できます。複数のフィールドのインデックス構成を指定するには、複数の pgsearch.field() 関数を呼び出し、二重縦棒(||)を使用して関数を連結します。詳細については、このテーブルの前の情報を参照してください。

datetime_fields

  • DATE

  • DATE[]

  • TIMESTAMP

  • TIMESTAMP[]

  • TIMESTAMPTZ

  • TIMESTAMPTZ[]

  • TIME

  • TIME[]

  • TIMETZ

  • TIMETZ[]

インデックスを作成する日付と時刻のフィールド、および対応するインデックス構成。このパラメーターを空のままにすると、UTC タイムゾーンと RFC 3339 形式が使用されます。

  • <datetime_fields> のインデックス <日時フィールド>. にパラメーターを設定

    サポートされているインデックス

    サポートされているインデックス設定項目:

    fast: フィールドにランダムに高速アクセスできるかどうかを指定します。この設定項目を使用すると、スコアリングとフィルタリングを高速化できます。既定値: true。

    :
  • pgsearch.field() 関数。

    pgsearch.field() 関数を呼び出して、特定のフィールドのインデックス構成を生成できます。複数のフィールドのインデックス構成を指定するには、複数の pgsearch.field() 関数を呼び出し、二重縦棒(||)を使用して関数を連結します。詳細については、このテーブルの前の情報を参照してください。

レコード

pgsearch 拡張機能は、3 つのタイプのレコードをサポートしています。

  • raw: 単語分割を実行しません。

  • freq: 行 ID と用語頻度を記録します。

  • position: 行 ID、用語頻度、および出現位置を記録します。

トークナイザー

pgsearch 拡張機能は、jieba、ngram、lindera、en_stem、whitespace など、さまざまな組み込みトークナイザーを提供します。トークナイザーは、pg_jieba または zhparser 拡張機能をインストールする必要なく、ビジネス要件を満たすことができます。

トークナイザー名

説明

構成

default

スペースと句読点に基づいてテキストをセグメント化し、テキストを小文字に変換します。このトークナイザーは、長さが 255 バイトを超える term を除外します。

{type: "default"}

raw

テキストをセグメント化しません。

{type: "raw"}

en_stem

テキストをスペースと句読点に基づいてセグメント化し、小文字に変換してから、各 term の語幹を抽出します。このトークナイザーは、長さが 40 文字を超える term を除外します。

{type: "en_stem"}

whitespace

スペースに基づいてテキストをセグメント化します。

{type: "whitespace"}

ngram

次のパラメーターを使用して、テキストを n-gram のシーケンスにセグメント化します。 n-gram は、長さ n の文字シーケンスです。

  • min_gram: 各 n-gram の最小長。たとえば、min_gram パラメーターを 2 に設定すると、各 n-gram には最小 2 文字が含まれます。

  • max_gram: 各 n-gram の最大長。たとえば、max_gram パラメーターを 5 に設定すると、各 n-gram には最大 5 文字が含まれます。

  • prefix_only: 単語の先頭からのみ n-gram を生成して、すべての n-gram が単語のプレフィックスになるようにするかどうかを指定します。有効な値: true および false。 prefix_only パラメーターを false に設定すると、min_gram および max_gram パラメーターの範囲内で要件を満たす文字のすべての組み合わせから n-gram を生成できます。

{type: "ngram", min_gram: 1, max_gram: 2, prefix_only: true}

chinese_compatible

スペースと句読点に基づいてテキストをセグメント化します。これは中国語のテキストに適しています。連続した中国語以外の文字の場合、トークンが生成されます。個別の漢字の場合、個別のトークンが生成されます。句読点などの数字またはアルファベット以外の文字の場合、トークンは生成されません。たとえば、「我爱吃橙子 oranges!12」という文字列は、7 つのトークンを含む「我, 爱, 吃, 橙, 子, oranges, 12」にセグメント化されます。

{type: "chinese_compatible"}

chinese_lindera

lindera トークナイザーと CC-CEDICT 辞書に基づいてテキストをセグメント化します。

{type: "chinese_lindera"}

korean_lindera

lindera トークナイザーと KoDic 辞書に基づいてテキストをセグメント化します。

{type: "korean_lindera"}

japanese_lindera

lindera トークナイザーと IPADIC 辞書に基づいてテキストをセグメント化します。

{type: "japanese_lindera"}

jieba

jieba トークナイザーに基づいてテキストをセグメント化します。これはほとんどの中国語のテキストに適しています。 jieba トークナイザーは、カスタム単語分割辞書とストップワード辞書をサポートしています。詳細については、「カスタム単語分割辞書を構成する」および「ストップワード辞書を構成する」を参照してください。

  • hmm: 隠れマルコフモデル(HMM)による単語分割を有効にするかどうかを指定します。デフォルト値: true。このパラメーターを true に設定すると、トークナイザーは HMM を使用して語彙外の単語を処理します。 HMM による単語分割は、コンテキスト情報に基づいて単語境界を決定し、単語分割の精度を向上させます。辞書が比較的完全な場合、このパラメーターを false に設定して HMM による単語分割を無効にすることができます。これにより、単語分割の処理が高速化されます。

  • search: 単語分割の最も細かい粒度を使用するかどうかを指定します。デフォルト値: true。これは長い単語をさらにセグメント化し、フレーズの一致精度を向上させます。このパラメーターを false に設定すると、テキストは粗い粒度でセグメント化されます。たとえば、「南京市长江大桥」というテキストは、search パラメーターを true に設定すると「南京/京市/南京市/长江/大桥/长江大桥」にセグメント化されます。 search パラメーターを false に設定すると、テキストは「南京市/长江大桥」にセグメント化されます。

説明

V7.2.1.0 以降の AnalyticDB for PostgreSQL V7.0 インスタンスのみが hmm および search パラメーターをサポートしています。

{type: "jieba",hmm=>true,search=>true}

pgsearch.tokenizer() 関数を呼び出して、トークナイザーの [設定項目] の文字列を生成できます。これにより、構成プロセスが簡素化されます。次のセクションでは、構文とパラメーターについて説明します。

構文

pgsearch.tokenizer(<name>, <min_gram>, <max_gram>, <prefix_only>, <search>, <hmm>, <dict>,<stopword>,<lowercase>,<remove_long>, <stemmer>);

パラメーター

  • name: トークナイザーの名前(テキスト型)。有効な値については、このトピックの「トークナイザー」セクションを参照してください。

  • min_grammax_gramprefix_onlysearchhmm パラメーターの詳細については、このトピックの「トークナイザー」セクションを参照してください。

  • dict: jieba トークナイザーで使用される単語分割辞書の名前(テキスト型)。詳細については、「カスタム単語分割辞書を構成する」を参照してください。

  • stopword: ストップワード辞書の名前(テキスト型)。デフォルトでは、このパラメーターを指定する必要はありません。詳細については、「ストップワード辞書を構成する」を参照してください。

  • lowercase: キーワードを小文字に変換するかどうかを指定します(ブール型)。デフォルト値: true。

  • remove_long: 削除するキーワードの長さ(整数型)。デフォルトでは、このパラメーターを指定する必要はありません。このパラメーターを設定した後、pgsearch.tokenizer() は長さが remove_long バイト以上であるキーワードを除外して削除します。各漢字は 3 バイトを占めます。

  • stemmer: 抽出する語幹(テキスト型)。デフォルトでは、このパラメーターを指定する必要はありません。このパラメーターを設定すると、語幹が抽出されます。たとえば、runrunningrunsran という単語は run に切り詰められます。どの run を検索しても、関連する結果を取得できます。ステミングは英語でのみサポートされており、値を en に設定する必要があります。

重要

V7.2.1.0 以降の AnalyticDB for PostgreSQL インスタンスのみが pgsearch.tokenizer() 関数をサポートしています。 V7.2.1.0 以降の AnalyticDB for PostgreSQL インスタンスのインデックスを作成するには、pgsearch.tokenizer() 関数を呼び出す必要があります。そうしないと、jieba トークナイザーのカスタム単語分割辞書とストップワード辞書が有効になりません。

インデックス作成の例

  • text_fields パラメーターを使用してインデックスを作成します。

    -- ngram トークナイザーを使用します。 ngram トークナイザーのすべての構成フィールドを指定する必要があります。
    CALL pgsearch.create_bm25(
        index_name => 'search_idx',
        table_name => 'mock_items',
        text_fields => '{description: { tokenizer: {type: "ngram", min_gram: 2, max_gram: 3, prefix_only: false}}}'
    );
    
    -- jieba トークナイザーを使用します。
    CALL pgsearch.create_bm25(
        index_name => 'search_idx',
        table_name => 'mock_items',
        text_fields => '{description: { tokenizer: {type: "jieba"}}}'
    );
    
    -- lindera トークナイザーを使用します。
    CALL pgsearch.create_bm25(
        index_name => 'search_idx',
        table_name => 'mock_items',
        text_fields => '{description: { tokenizer: {type: "chinese_lindera"}}}'
    );
    -- 複数のフィールドにインデックスを作成します。
    CALL pgsearch.create_bm25(
        index_name => 'search_idx',
        table_name => 'mock_items',
        text_fields => '{description: {fast: false, filednorms: true, tokenizer: {type: "jieba"}}, category: {}}',
        datetime_fields => '{created_at: {fast: true}, last_updated_date: {fast: true}}',
        numeric_fields => '{rating: {fast: true}}',
        json_fields => '{metadata: {fast: true, expand_dost: true, tokenizer: {type: "en_stem"}, record: "position"}}',
        boolean_fields => '{in_stock: {fast: true} }'
    );
    
    -- ほとんどの場合、text_fields および json_fields パラメーターの tokenizer フィールドのみを構成できます。その他のパラメーターにはデフォルト値を使用します。
    CALL pgsearch.create_bm25(
        index_name => 'search_idx',
        table_name => 'mock_items',
        text_fields => '{description: {tokenizer: {type: "jieba"}}, category: {}}',
        datetime_fields => '{created_at: {}, last_updated_date: {}}',
        numeric_fields => '{rating: {}}',
        json_fields => '{metadata: {tokenizer: {type: "en_stem"}}}',
        boolean_fields => '{in_stock: {} }'
    );
  • pgsearch.field() 関数と pgsearch.tokenizer() 関数を使用してインデックスを作成し、単語分割の効果をクエリします。

    -- description カラムの fast パラメーターを true に設定し、record パラメーターを position に設定し、tokenizer パラメーターを jieba に設定します。 jieba トークナイザーでは、非検索モードが構成され、user_dict がカスタム単語分割辞書として使用され、CN_SIMPLE が組み込みストップワードとして使用されます。
    -- category カラムにはデフォルト構成を使用します。
    -- 2 つのカラムの構成は、二重縦棒(||)を使用して連結できます。
    CALL pgsearch.create_bm25(
        index_name => 'search_idx',
        table_name => 'mock_items',
        text_fields => pgsearch.field('description', fast=>true, record=>'position', tokenizer=>pgsearch.tokenizer('jieba', search=>false, dict=>'user_dict', stopword=>'CN_SIMPLE')) 
                        || pgsearch.field('category')
    );
    
    CALL pgsearch.create_bm25(
        index_name => 'search_idx',
        table_name => 'mock_items',
        text_fields => pgsearch.field('description', tokenizer=>pgsearch.tokenizer('jieba'),
        datetime_fields => '{created_at: {}, last_updated_date: {}}',
        numeric_fields => '{rating: {}}',
        json_fields => '{metadata: {tokenizer: {type: "en_stem"}}}',
        boolean_fields => '{in_stock: {} }'
    );
    
    -- 指定された jieba トークナイザーを使用して単語分割の効果をクエリします。
    SELECT pgsearch.tokenizer(pgsearch.tokenizer('jieba', hmm=>false, search=>false, dict=>'custom_dict_1'), '永和服装饰品有限公司');
             tokenizer         
    
    -- さまざまなフィルターを使用して単語分割結果を処理します。
    SELECT pgsearch.tokenizer(
        pgsearch.tokenizer('jieba',
        search=>false, dict=>'user_dict', stopword=>'CN_SIMPLE',
        lowercase=>false, remove_long=>27, stemmer=>'en')::text,
        '永和服装饰品有限公司。 Shoping'
    );

インデックスの構成をクエリする

SELECT * FROM pgsearch.schema_bm25('index_name'::regclass);

インデックスを削除する

DROP INDEX index_name;

インデックスを再構築する

REINDEX INDEX index_name;

検索構文

@@@ 演算子

k 近傍法(KNN)検索で @@@ 演算子を使用して、BM25 スコアに基づいて検索結果をソートし、上位の結果を返すことができます。

構文

SELECT * FROM <table_name> 
ORDER BY <index_col> @@@ pgsearch.config('<query>');

パラメーター

  • <table_name>: テーブルの名前。

  • <index_col>: インデックスを作成するときに指定されたインデックスフィールドの名前。 query パラメーターで指定された検索キーワードに含まれる最初のインデックスフィールドを使用することをお勧めします。

  • <query>: 検索キーワード。

  • pgsearch.config: 検索関数。文字列またはその他のタイプの検索オブジェクトをサポートします。検索オブジェクトは、任意の粒度で組み合わせることができます。検索キーワードが pgsearch.config() 関数に渡されると、pgsearch.parse() 関数は検索キーワードを検索オブジェクトに暗黙的に解析します。次のサンプルステートメントは、同じクエリ効果を提供します。

  • SELECT * FROM mock_items 
    ORDER BY description @@@ pgsearch.config('description:socks');
    
    SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
      query => pgsearch.parse('description:socks')
    );

基本的なクエリ

特定のフィールド検索

テキストフィールド検索

指定された単語またはフレーズを含む行をクエリします。フレーズにスペースが含まれている場合は、フレーズを二重引用符(")で囲む必要があります。

「keyboard」という単語または「hello world」というフレーズを含む行をクエリします。

SELECT * FROM mock_items 
ORDER BY description @@@ pgsearch.config('description:keyboard');

-- スペース区切りのフレーズ「hello world」を含む行をクエリします。
SELECT * FROM mock_items 
ORDER BY description @@@ pgsearch.config('description:"hello world"');

JSON フィールド検索

{"metadata": {"color": "white"}} を含む行をクエリします。

SELECT * FROM mock_items 
ORDER BY metadata @@@ pgsearch.config('metadata.color:white');

DATETIME フィールド検索

DATETIME フィールドをクエリすると、UTC タイムゾーンと RFC 3339 フォーマットが使用されます。

SELECT * FROM mock_items ORDER BY created_at @@@ pgsearch.config('created_at:"2023-05-01T09:12:34Z"') LIMIT 10;

SELECT * FROM mock_items ORDER BY created_at @@@ pgsearch.config('created_at:"2023-05-01T04:12:34-05:00"') LIMIT 10;

近接演算子検索

~ 演算子を使用して、単語で区切られた語句をクエリできます。たとえば、description フィールドには、「ergonomic metal keyboard」という語句が含まれています。「ergonomic」と「keyboard」は単語で区切られているため、次の文を実行して「ergonomic metal keyboard」をクエリできます。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config('description:"エルゴノミクス キーボード"~1');

効率的なフィルター検索

フィルターは、BM25 インデックスが作成された数値フィールドとブール型フィールドのみに適しています。標準 SQL 文の WHERE 句と比較して、フィルター検索はより高速に結果を取得できます。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config('description:キーボード AND rating:<4');

ランク向上検索

検索キーワードの結果ランキングを向上させたい場合は、^ 文字の後に改善係数を付けることができます。係数は、検索結果の BM25 スコアを上げるために使用されます。これにより、結果のランキングが向上します。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config('description:キーボード^2 OR category:家電^3');

ブール演算子検索

複数のキーワードをフィルタリングするには、ANDOR、および NOT 演算子を使用できます。かっこ () を使用して、グループ化と操作シーケンスを管理できます。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config('description:キーボード OR category:おもちゃ');

演算子検索の設定

IN 演算子を使用すると、1 つ以上の OR 演算子と同じ機能を提供できます。IN 演算子は消費する CPU リソースが少なくなります。

IN 演算子を使用する場合、各フレーズはスペースで区切られ、各フレーズの単語分割結果は複数のトークンを含むことはできません。中国語の単語分割から生成されるトークンの数はトークナイザーによって異なり、制御が困難です。したがって、IN 演算子は英語にのみ適用できます。中国語のシナリオでは、この構文の代わりに複数の OR 演算子を使用することをお勧めします。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config('description:IN [キーボード おもちゃ]');

制限およびオフセットベースの検索

OFFSET 句と LIMIT 句を使用して検索を実行できます。

SELECT * FROM mock_items
ORDER BY description @@@ pgsearch.config('description:socks') OFFSET 2 LIMIT 10;

高度なクエリ

単語分割結果を取得する

pgsearch.tokenizer() 関数を使用して、単語分割結果を取得できます。関数は、セグメント化された単語で構成される配列を返します。

構文

SELECT pgsearch.tokenizer(<tokenizer_config>, <query_str>);

パラメーター

  • tokenizer_config: トークナイザーの構成情報を含む JSON 文字列。同じ名前の pgsearch.tokenizer() 関数を呼び出して、トークナイザー [設定項目] の文字列を生成することもできます。詳細については、このトピックの「トークナイザー」セクションを参照してください。

  • query_str: セグメント化する文字列。

SELECT pgsearch.tokenizer('{type: "ngram", min_gram: 1, max_gram: 2, prefix_only: true}', 'hell');
SELECT pgsearch.tokenizer('{type: "jieba"}', '数据仓库');
SELECT pgsearch.tokenizer(pgsearch.tokenizer('jieba'), '永和服装饰品有限公司');

用語セット検索

用語の配列に含まれるキーワードを含む行を検索できます。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query =>  pgsearch.term_set(
	    terms => ARRAY[
	        pgsearch.term(field => 'description', VALUE => 'socks'),
	        pgsearch.term(field => 'description', VALUE => 'novel')
            
	    ]
	)
);

パラメーター

  • field: 検索フィールド。このパラメーターを空のままにすると、すべてのインデックスフィールドが検索されます。

  • terms: 検索する用語の配列。

説明

デフォルトでは、トークナイザーはインデックス付きキーワードを小文字に変換します。 pgsearch.term() 関数で大文字のキーワードを使用して関連するクエリ結果を取得することはできません。クエリには小文字のキーワードを使用することをお勧めします。

フレーズ検索

順序付けられたキーワードの配列を含む行をクエリできます。フレーズ検索を実行する前に、インデックスの record [設定項目] が position に設定されていることを確認してください。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query => pgsearch.phrase(
    field => 'description',
    phrases => ARRAY['little', 'red', 'riding' 'hood'],
        slop => 0
    )
);

パラメーター

  • field: 検索フィールド。このパラメーターを空のままにすると、すべてのインデックスフィールドが検索されます。

  • phrases: キーワードの配列。行に配列内のすべてのキーワードが含まれており、行内のキーワードの順序が配列内のキーワードの順序と同じである場合、その行が返されます。単語がすべてのキーワードと一致し、順序がキーワードの順序と一致する場合にのみ、行が返されます。

  • slop: 2 つのキーワード間の最大距離。このパラメーターはオプションです。値 0 は、一致する行が配列内のキーワードと同じ順序であり、すべての 2 つのキーワードが隣接している必要があることを指定します。たとえば、little、red、riding、hood というキーワードは、行内で連続してソートする必要があります。 0 より大きい値は、キーワードが非連続になる可能性があることを指定します。たとえば、一致する行の little、red、riding、hood というキーワードのいずれか 2 つの間に、他の単語が存在する可能性があります。

フレーズプレフィックス検索

順序付けられたキーワードの配列で始まるコンテンツを含む行を検索できます。フレーズプレフィックス検索を実行する前に、検索フィールドにインデックスが作成されていることを確認してください。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query => pgsearch.phrase_prefix(
    field => 'description',
    phrases => ARRAY['little', 'red', 'riding' 'hood'],
        max_expansion => 1
    )
);

パラメーター

  • field: 検索フィールド。このパラメーターを空のままにすると、すべてのインデックスフィールドが検索されます。

  • phrases: キーワードの配列。クエリパラメーターはサブクエリを指定します。指定された順序付けられたキーワードの配列で始まる文字列をクエリできます。たとえば、phrases パラメーターを ARRAY['little', 're'] に設定すると、「little re」がプレフィックスとして使用されます。この場合、「little red riding hood」が返される可能性があります。

  • max_expansion: プレフィックスから展開できるキーワード変数の最大数。このパラメーターはオプションです。このパラメーターは検索範囲を絞り込みます。

単語セグメント検索(tokenizer_terms

指定されたトークナイザーを使用してクエリテキストをセグメント化し、生成されたトークンをクエリできます。 pgsearch.tokenizer_terms() 関数は、指定されたトークン間でのブールロジックの使用をサポートしています。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
pgsearch.tokenizer_terms('description', '朝阳百货', pgsearch.tokenizer('jieba'), 'OR'));

パラメーター

  • tokenizer: pgsearch.tokenizer() 関数で指定されたトークナイザーの構成文字列。デフォルト値: jieba。

  • operator: 単語分割後のトークン間のブールロジックを説明するために使用される演算子。有効な値: OR および AND。デフォルト値: OR。たとえば、「朝阳百货」という単語は「朝阳/百货」にセグメント化されます。 operator パラメーターを OR に設定すると、「朝阳」または「百货」を含む行が返されます。 operator パラメーターを AND に設定すると、「朝阳」と「百货」の両方を含む行のみが返されます。

すべて検索

インデックスフィールドを含み、同じスコア 1.0 を持つすべての行を検索できます。すべての検索結果は、プリファレンスが等しくなります。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query =>  pgsearch.all()
);

ブール検索

サブクエリで定義された論理関係を使用してフィルターされた行をクエリできます。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query => pgsearch.boolean(
	    should => ARRAY[
		    pgsearch.parse('description:socks'),
		    pgsearch.phrase_prefix(field => 'description', phrases => ARRAY['book']),
		    pgsearch.term(field => 'description', VALUE => 'writer'),
		    pgsearch.fuzzy_term(field => 'description', VALUE => 'wow')
	    ],
        must_not => ARRAY[
            pgsearch.term(field => 'description', VALUE => 'writer')
        ],
        must => ARRAY[
            pgsearch.term(field => 'rating', VALUE => 4)
        ]
    )
);
-- should、must_not、must パラメーターの 1 つ以上を構成できます。
SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query => pgsearch.boolean(
	    should => pgsearch.parse('description:socks')
    )
);

パラメーター

  • must: 検索オブジェクトの配列で一致する必要がある条件。 must パラメーターで指定されたすべての条件に一致する行が返される可能性があります。

  • must_not: 検索オブジェクトの配列で一致してはならない条件。 must_not パラメーターで指定された条件に一致する行は返されません。

  • should: must パラメーターが存在しない場合に、検索オブジェクトの配列で一致する可能性のある条件。

  • must パラメーターが存在しない場合、should パラメーターで指定された少なくとも 1 つの条件に一致する行が返されます。

ランクブースト検索

ランクブースト検索を使用してサブクエリのスコアを増やすことで、サブクエリの結果ランキングをブーストできます。この例では、query => pgsearch.parse('description:socks') が使用されています。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query => pgsearch.boost(query => pgsearch.parse('description:socks'), boost => 2)
);

パラメーター

  • boost: 各結果スコアに乗算される係数。

  • query: 検索オブジェクト。

定数スコア検索

定数スコアを使用して、サブクエリで指定された条件に一致する行をクエリできます。この例では、query => pgsearch.all() が使用されています。これにより、サブクエリで不要なスコア計算が回避されます。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query => pgsearch.const_score(query => pgsearch.all(), score => 2)
);

パラメーター

  • score: サブクエリの各結果の定数スコア。

  • query: 検索オブジェクト。

最大選言検索

1 つ以上のサブクエリに一致する行をクエリできます。より多くの条件に一致する行は、より高い BM25 スコアを取得できます。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query => pgsearch.disjunction_max(
      disjuncts => ARRAY[
          pgsearch.parse('description:socks'),
          pgsearch.parse('description:Generic')
      ],
      tie_breaker => 0.75
    )
);

パラメーター

  • disjuncts: 1 つ以上のサブクエリで構成される配列。

  • tie_breaker: 行が複数のサブクエリに一致する場合に、行の BM25 スコアを調整するために使用される係数。このパラメーターはオプションです。行が複数のサブクエリに一致する場合、行の BM25 スコアは次のルールを使用して計算されます。まず、最適に一致するサブクエリの BM25 スコアを計算します。次に、その他の一致するサブクエリの増分スコアを前の BM25 スコアに追加します。前の例では、pgsearch.parse('description:socks') サブクエリでの行の BM25 スコアが 1.0 で、pgsearch.parse('description:Generic') サブクエリでの行の BM25 スコアが 0.5 の場合、行の最終的な BM25 スコアは次の式を使用して計算されます。1.0 + 0.75 × 0.5 = 1.375。

空の検索

テストシナリオまたはエッジケースでプレースホルダーとして空の検索を使用できます。この場合、行は返されません。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query => pgsearch.empty()
);

あいまい語検索

検索キーワードのあいまい語を含む行をクエリできます。スペルが完全に正しくなくても、検索結果が返される可能性があります。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query => pgsearch.fuzzy_term(
      field => 'description', 
      VALUE => 'wow',
      distance => 2,
      tranposition_cost_one => true,
      prefix => true)
);

パラメーター

  • field: 検索フィールド。このパラメーターを空のままにすると、すべてのインデックスフィールドが検索されます。

  • value: 検索キーワード。レーベンシュタイン距離に基づくあいまい一致を使用して、指定されたキーワードに類似した結果が検索されます。

  • distance: 指定されたフィールドを一致させるための最大編集距離(1 文字の変更の最大数)。このパラメーターはオプションです。デフォルト値: 2。最大値: 2。

  • tranposition_cost_one: 2 つの隣接する文字の交換をレーベンシュタイン距離の計算で 1 回の編集と見なすかどうかを指定します。このパラメーターはオプションです。デフォルト値: true。 tranposition_cost_one パラメーターを false に設定すると、交換は 2 つの個別の編集(削除と挿入)と見なされます。

  • prefix: 検索キーワードのプレフィックスをあいまい編集距離の計算から除外するかどうかを指定します。このパラメーターはオプションです。デフォルト値: true。 prefix パラメーターを false に設定すると、検索キーワード全体が計算に使用されます。

範囲検索

特定の範囲内の値を含む行をクエリできます。範囲検索は、numeric_fields パラメーターと datetime_fields パラメーターに適しています。

SELECT * FROM mock_items ORDER BY rating @@@ pgsearch.config(
    query => pgsearch.range(
        field => 'rating',
        RANGE => '[1,4)'::int4range
  )
);

パラメーター

  • field: 検索フィールド。このパラメーターを空のままにすると、すべてのインデックスフィールドが検索されます。

  • range: 指定されたフィールドを一致させるための値の範囲。次の範囲タイプがサポートされています: INT4RANGE、INT8RANGE、DATERANGE、TSRANGE、TSTZRANGE。

正規表現検索

特定の正規表現に一致する単語を含む行をクエリできます。

SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query => pgsearch.regex(
		field => 'description',
		PATTERN => '(glass|screen|like|cloth|phone)'
	)
);
SELECT * FROM mock_items ORDER BY description @@@ pgsearch.config(
    query => pgsearch.regex(
		field => 'description',
		PATTERN => '(.*screen.*)'
	)
);

パラメーター

  • field: 検索フィールド。このパラメーターを空のままにすると、すべてのインデックスフィールドが検索されます。

  • pattern: 正規表現パターン。

その他

BM25 スコアを取得する

@@@ 演算子を SELECT ステートメントの先頭に配置し、AS キーワードを使用して BM25 スコアを取得できます。

デフォルトでは、ORDER BY 句は AnalyticDB for PostgreSQL データベースの昇順の結果を返します。 BM25 スコアが高いほど、結果ランキングが高くなります。この場合、BM25 スコアの負の値が返されます。たとえば、BM25 スコアが 2.86 の場合、戻り値は -2.86 です。 BM25 スコアは、text_fields パラメーターと json_fields パラメーターで指定されたフィールドの検索に対してのみ計算されます。 numeric_fields、datetime_fields、boolean_fields パラメーターで指定されたフィールドの検索では、BM25 スコアを計算できません。

構文

SELECT *, mock_items @@@ pgsearch.config(<query>) as BM25
FROM mock_items
ORDER BY BM25;

-- 1. 文字列フィールドのみで全文検索を実行します。 BM25 スコアが返されます。
SELECT description, rating, description @@@ pgsearch.config('description:socks') AS bm25 FROM mock_items ORDER BY bm25 limit 1;

-- 2. 文字列フィールドで全文検索を実行し、数値フィールドでデータをフィルターします。 BM25 スコアが返されます。
SELECT description, rating, description @@@ pgsearch.config('description:socks AND rating:4') AS bm25 FROM mock_items ORDER BY bm25 limit 4;
 
-- 3. JSON フィールドで全文検索を実行します。 BM25 スコアが返されます。
SELECT metadata, metadata @@@ pgsearch.config('metadata.color:White') AS bm25 FROM mock_items ORDER BY bm25 LIMIT 1;

-- 4. ランクフィールドで範囲検索を実行します。 BM25 スコアは計算できません。デフォルト値 -1 が返されます。
 SELECT description, rating, rating @@@ pgsearch.config('rating:[4 TO 5]') AS bm25 FROM mock_items ORDER BY bm25 LIMIT 1;

クエリ結果

-- 1. 文字列フィールドのみで全文検索を実行します。 BM25 スコアが返されます。
   description  | rating |    bm25    
---------------+--------+------------
 Generic socks |      4 | -2.1048825
(1 row)

-- 2. 文字列フィールドで全文検索を実行し、数値フィールドでデータをフィルターします。 BM25 スコアが返されます。
 description  | rating |    bm25    
---------------+--------+------------
 Generic socks |      4 | -3.1081846
(1 row)

-- 3. JSON フィールドで全文検索を実行します。 BM25 スコアが返されます。
                metadata                 |   bm25    
-----------------------------------------+-----------
 {"color": "White", "location": "China"} | -3.453373
(1 row)

-- 4. ランクフィールドで範囲検索を実行します。 BM25 スコアは計算できません。デフォルト値 -1 が返されます。
  description    | rating | bm25 
------------------+--------+------
 Plastic Keyboard |      4 |   -1
(1 row)