これはPGroonga 2.X and 3.X用のドキュメントです。古いPGroongaを使っているならPGroonga 1.xのドキュメントを見てください。

jsonb型以外の型用の&@~演算子

1.2.2で追加。

&?演算子は1.2.2から非推奨です。代わりに&@~演算子を使ってください。

概要

&@~演算子はクエリーを使って全文検索を実行します。

クエリーの構文はWeb検索エンジンで使われている構文と似ています。たとえば、クエリーでキーワード1 OR キーワード2と書くとOR検索できます。キーワード1 キーワード2と書くとAND検索できます。キーワード1 -キーワード2と書くとNOT検索できます。

構文

使い方は3つあります。

column &@~ query
column &@~ (query, weights, index_name)::pgroonga_full_text_search_condition
column &@~ (query, weights, scorers, index_name)::pgroonga_full_text_search_condition_with_scorers
column &@~ pgroonga_condition(query,
                              weights,
                              scorers,
                              schema_name,
                              index_name,
                              column_name,
                              fuzzy_max_distance_ratio)

1つ目の使い方は他の使い方よりもシンプルです。多くの場合は1つ目の使い方で十分です。

2つ目の使い方は検索スコアーを最適化するときに便利です。たとえば、ブログアプリケーションで「タイトルは本文よりも重要」という検索を実現できます。

2つ目の使い方は2.0.4から使えます。

3つ目の使い方は検索スコアーをより最適化するときに便利です。たとえば、キーワードスタッフィング対策を実現することができます。

3つ目の使い方は2.0.6から使えます。

4つ目の使い方はpgroonga_condition関数を使います。 pgroonga_condition関数を使うと2つ目と3つ目の使い方が実現できます。 3.1.6以降はこの構文を使ってください。詳しくはpgroonga_condition関数をご覧ください。

以下は1つ目の使い方の説明です。

column &@~ query

columnは検索対象のカラムです。型はtext型、text[]型、varchar型のどれかです。

queryは全文検索用のクエリーです。columntext型またはtext[]型ならquerytext型です。columnvarchar型ならqueryvarchar型です。

qeuryではGroongaのクエリー構文を使います。

以下は2つ目の使い方の説明です。

column &@~ (query, weights, index_name)::pgroonga_full_text_search_condition

columnは検索対象のカラムです。型はtext型、text[]型、varchar型のどれかです。

queryは全文検索用のクエリーです。columntext型またはtext[]型ならquerytext型です。columnvarchar型ならqueryvarchar型です。

weightsは、検索対象のカラムの重要度です。int[]型です。

もし、columntext型かvarchar型なら、最初の要素がカラムの値の重要度になります。columntext[]型なら、同じ位置の値がその値の重要度になります。

weightsNULLにできます。weightsの要素もNULLにできます。対応する重要度がNULLの場合は重要度は1になります。

重要度が0の場合は対応する値を無視します。たとえば、ARRAY[1, 0, 1]は2番目の値は検索しないという意味になります。

index_nameは対応するPGroongaのインデックス名です。text型です。

index_nameにはNULLを指定できます。

これはシーケンシャルサーチのときにもPGroongaのインデックスに指定した検索オプションを使えるようにするために使われます。

2.0.6から使えます。

以下は3つ目の使い方の説明です。

column &@~ (query, weights, scorers, index_name)::pgroonga_full_text_search_condition_with_scorers

columnは検索対象のカラムです。型はtext型、text[]型、varchar型のどれかです。

queryは全文検索用のクエリーです。columntext型またはtext[]型ならquerytext型です。columnvarchar型ならqueryvarchar型です。

weightsは、検索対象のカラムの重要度です。int[]型です。

もし、columntext型かvarchar型なら、最初の要素がカラムの値の重要度になります。columntext[]型なら、同じ位置の値がその値の重要度になります。

weightsNULLにできます。weightsの要素もNULLにできます。対応する重要度がNULLの場合は重要度は1になります。

重要度が0の場合は対応する値を無視します。たとえば、ARRAY[1, 0, 1]は2番目の値は検索しないという意味になります。

scorersはそれぞれの値のスコアーを計算する処理です。text[]型です。もし、columntext型かvarchar型なら、最初の要素がカラムの値のスコアーを計算します。columntext[]型なら、同じ位置の値がその値のスコアーを計算します。

scorersNULLにできます。scorersの要素もNULLにできます。対応するスコアラーがNULLの場合は単語の出現数をスコアーにするスコアラーを使います。

スコアラーの詳細はGroongaのスコアラーのドキュメントを参照してください。

スコアラーの最初の引数には$indexを指定しなければいけないことに注意してください。

例:

'scorer_tf_at_most($index, 0.25)'

$indexは内部的に適切なGroongaのインデックス名に置き換えられます。

index_nameは対応するPGroongaのインデックス名です。text型です。

index_nameにはNULLを指定できます。

これはシーケンシャルサーチのときにもPGroongaのインデックスに指定した検索オプションを使えるようにするために使われます。

2.0.6から使えます。

qeuryではGroongaのクエリー構文を使います。

演算子クラス

この演算子を使うには次のどれかの演算子クラスを指定する必要があります。

使い方

例に使うサンプルスキーマとデータは次の通りです。

CREATE TABLE memos (
  id integer,
  content text
);

CREATE INDEX pgroonga_content_index ON memos USING pgroonga (content);
INSERT INTO memos VALUES (1, 'PostgreSQLはリレーショナル・データベース管理システムです。');
INSERT INTO memos VALUES (2, 'Groongaは日本語対応の高速な全文検索エンジンです。');
INSERT INTO memos VALUES (3, 'PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。');
INSERT INTO memos VALUES (4, 'groongaコマンドがあります。');

&@~演算子を使うとキーワード1 キーワード2のように複数のキーワードを指定して全文検索できます。キーワード1 OR キーワード2のようにOR検索することもできます。

SELECT * FROM memos WHERE content &@~ 'PGroonga OR PostgreSQL';
--  id |                                  content
-- ----+---------------------------------------------------------------------------
--   3 | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。
--   1 | PostgreSQLはリレーショナル・データベース管理システムです。
-- (2 rows)

「タイトルは本文よりも重要」も実現できます。

例に使うサンプルスキーマとデータは次の通りです。

DROP TABLE IF EXISTS memos;
CREATE TABLE memos (
  title text,
  content text
);

CREATE INDEX pgroonga_memos_index
    ON memos
 USING pgroonga ((ARRAY[title, content]));
INSERT INTO memos VALUES ('PostgreSQL', 'PostgreSQLはリレーショナル・データベース管理システムです。');
INSERT INTO memos VALUES ('Groonga', 'Groongaは日本語対応の高速な全文検索エンジンです。');
INSERT INTO memos VALUES ('PGroonga', 'PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。');
INSERT INTO memos VALUES ('コマンドライン', 'groongaコマンドがあります。');

より指定したクエリーにマッチしたレコードを探すためにはpgroonga_score関数を使えます。

SELECT *, pgroonga_score(tableoid, ctid) AS score
  FROM memos
 WHERE ARRAY[title, content] &@~
       ('Groonga OR PostgreSQL',
        ARRAY[5, 1],
        'pgroonga_memos_index')::pgroonga_full_text_search_condition
 ORDER BY score DESC;
--      title      |                                  content                                  | score 
-- ----------------+---------------------------------------------------------------------------+-------
--  Groonga        | Groongaは日本語対応の高速な全文検索エンジンです。                         |     6
--  PostgreSQL     | PostgreSQLはリレーショナル・データベース管理システムです。                |     6
--  PGroonga       | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。 |     2
--  コマンドライン | groongaコマンドがあります。                                               |     1
-- (4 rows)

-- pgroonga_condition()を使う
SELECT *, pgroonga_score(tableoid, ctid) AS score
  FROM memos
 WHERE ARRAY[title, content] &@~
       pgroonga_condition('Groonga OR PostgreSQL',
                          weights => ARRAY[5, 1],
                          index_name => 'pgroonga_memos_index')
 ORDER BY score DESC;
--      title      |                                  content                                  | score 
-- ----------------+---------------------------------------------------------------------------+-------
--  Groonga        | Groongaは日本語対応の高速な全文検索エンジンです。                         |     6
--  PostgreSQL     | PostgreSQLはリレーショナル・データベース管理システムです。                |     6
--  PGroonga       | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。 |     2
--  コマンドライン | groongaコマンドがあります。                                               |     1
-- (4 rows)

titleカラムに「Groonga」または「PostgreSQL」があるレコードの方がcontentカラムに「Groonga」または「PostgreSQL」がある方がスコアーが高いことを確認できます。

2番目の重みの値に0を指定するとcontentカラムを無視できます。

SELECT *, pgroonga_score(tableoid, ctid) AS score
  FROM memos
 WHERE ARRAY[title, content] &@~
       ('Groonga OR PostgreSQL',
        ARRAY[5, 0],
        'pgroonga_memos_index')::pgroonga_full_text_search_condition
 ORDER BY score DESC;
--    title    |                          content                           | score 
-- ------------+------------------------------------------------------------+-------
--  Groonga    | Groongaは日本語対応の高速な全文検索エンジンです。          |     5
--  PostgreSQL | PostgreSQLはリレーショナル・データベース管理システムです。 |     5
-- (2 rows)

-- pgroonga_condition()を使う
SELECT *, pgroonga_score(tableoid, ctid) AS score
  FROM memos
 WHERE ARRAY[title, content] &@~
       pgroonga_condition('Groonga OR PostgreSQL',
                          weights => ARRAY[5, 0],
                          index_name => 'pgroonga_memos_index')
 ORDER BY score DESC;
--    title    |                          content                           | score 
-- ------------+------------------------------------------------------------+-------
--  Groonga    | Groongaは日本語対応の高速な全文検索エンジンです。          |     5
--  PostgreSQL | PostgreSQLはリレーショナル・データベース管理システムです。 |     5
-- (2 rows)

スコアーの計算方法をカスタマイズできます。たとえば、contentカラムのスコアーを最大で0.5に制限できます。

SELECT *, pgroonga_score(tableoid, ctid) AS score
  FROM memos
 WHERE ARRAY[title, content] &@~
       ('Groonga OR PostgreSQL',
        ARRAY[5, 1],
        ARRAY[NULL, 'scorer_tf_at_most($index, 0.5)'],
        'pgroonga_memos_index')::pgroonga_full_text_search_condition_with_scorers
 ORDER BY score DESC;
--      title      |                                  content                                  | score 
-- ----------------+---------------------------------------------------------------------------+-------
--  Groonga        | Groongaは日本語対応の高速な全文検索エンジンです。                         |   5.5
--  PostgreSQL     | PostgreSQLはリレーショナル・データベース管理システムです。                |   5.5
--  PGroonga       | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。 |     1
--  コマンドライン | groongaコマンドがあります。                                               |   0.5
-- (4 rows)

-- pgroonga_condition()を使う
SELECT *, pgroonga_score(tableoid, ctid) AS score
  FROM memos
 WHERE ARRAY[title, content] &@~
       pgroonga_condition('Groonga OR PostgreSQL',
                          weights => ARRAY[5, 1],
                          scorers => ARRAY[NULL, 'scorer_tf_at_most($index, 0.5)'],
                          index_name => 'pgroonga_memos_index')
 ORDER BY score DESC;
--      title      |                                  content                                  | score 
-- ----------------+---------------------------------------------------------------------------+-------
--  Groonga        | Groongaは日本語対応の高速な全文検索エンジンです。                         |   5.5
--  PostgreSQL     | PostgreSQLはリレーショナル・データベース管理システムです。                |   5.5
--  PGroonga       | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。 |     1
--  コマンドライン | groongaコマンドがあります。                                               |   0.5
-- (4 rows)

クエリーの構文の詳細はGroongaのドキュメントを参照してください。

カラム名:@キーワードのようにカラム名:から始まる構文を使うことはできません。これはPGroongaで無効にしています。

前方一致検索のためにカラム名:^値という構文を使うことができません。前方一致検索には値*を使ってください。

参考