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

&@演算子

1.2.0で追加。

概要

&@演算子は1つのキーワードで全文検索を実行します。

構文

使い方は3つあります。

column &@ keyword
column &@ (keyword, weights, index_name)::pgroonga_full_text_search_condition
column &@ (keyword, weights, scorers, index_name)::pgroonga_full_text_search_condition_with_scorers

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

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

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

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

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

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

column &@ keyword

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

keywordは全文検索で使うキーワードです。columntext型またはtext[]型ならkeywordtext型です。columnvarchar型ならkeywordvarchar型です。

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

column &@ (keyword, weights, index_name)::pgroonga_full_text_search_condition

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

keywordは全文検索で使うキーワードです。columntext型またはtext[]型ならkeywordtext型です。columnvarchar型ならkeywordvarchar型です。

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 &@ (keyword, weights, scorers, index_name)::pgroonga_full_text_search_condition

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

keywordは全文検索で使うキーワードです。columntext型またはtext[]型ならkeywordtext型です。columnvarchar型ならkeywordvarchar型です。

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から使えます。

演算子クラス

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

使い方

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

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つキーワードで全文検索できます。

SELECT * FROM memos WHERE content &@ '全文検索';
--  id |                      content                      
-- ----+---------------------------------------------------
--   2 | Groongaは日本語対応の高速な全文検索エンジンです。
-- (1 row)

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

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

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関数を使うと「Groonga」により適したレコードを見つけられます。

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

contentカラムに「Groonga」を含むレコードよりも、titleカラムに「Groonga」を含むレコードのほうが高いスコアになっています。

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

SELECT *, pgroonga_score(tableoid, ctid) AS score
  FROM memos
 WHERE ARRAY[title, content] &@
       ('Groonga',
        ARRAY[5, 0],
        'pgroonga_memos_index')::pgroonga_full_text_search_condition
 ORDER BY score DESC;
--   title  |                      content                      | score 
-- ---------+---------------------------------------------------+-------
--  Groonga | Groongaは日本語対応の高速な全文検索エンジンです。 |     5
-- (1 row)

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

SELECT *, pgroonga_score(tableoid, ctid) AS score
  FROM memos
 WHERE ARRAY[title, content] &@
       ('Groonga',
        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
--  PGroonga       | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。 |   0.5
--  コマンドライン | groongaコマンドがあります。                                               |   0.5
-- (3 rows)

複数のキーワードで全文検索したいときやAND/ORを使った検索をしたいときは&@~演算子を使います。

複数のキーワードでOR全文検索をしたいときは&@|演算子を使います。

参考