これはPGroonga 2.X and 3.X用のドキュメントです。古いPGroongaを使っているならPGroonga 1.xのドキュメントを見てください。
SudachiDictは同義語辞書を提供しています。PGroongaでこれを使うことができます。
検索システムでSudachiDictにある同義語辞書を使う方法を説明します。ここではSudachiDictにある同義語辞書をシステム辞書として使います。さらに自分たちで定義した同義語辞書も使います。
SudachiDictベースのシステム同義語辞書のためのテーブルを作る必要があります。ここではこのテーブルの名前はsystem_thesaurus
にします。
CREATE TABLE system_thesaurus (
term text PRIMARY KEY,
synonyms text[]
);
このテーブルを同義語辞書として使うにはPGroongaのインデックスが必要です。このインデックスでは、同義語のキーとして使うterm
の演算子クラスにpgroonga_text_term_search_ops_v2
を指定しなければいけません。
CREATE INDEX system_thesaurus_term_index
ON system_thesaurus
USING pgroonga (term pgroonga_text_term_search_ops_v2);
SudachiDictにある同義語辞書の中身をsystem_thesaurus
に登録するためにGroonga synonymを使います。
Groonga synonymはRubyで書かれています。そのため、事前にRubyをインストールしておかないといけません。
Groonga synonymをインストールします。
gem install groonga-synonym
次のコマンドラインはSudachiDictにある同義語辞書の内容をsystem_thesaurus
に登録するINSERT
を生成します。
groonga-synonym-generate --format=pgroonga --table=system_thesaurus --output=system_thesaurus_data.sql
SudachiDictが関連情報を提供しているので生成されたデータには重みがついています。
このデータはpsql
内で\i
を使ってロードできます。
\i system_thesaurus_data.sql
ユーザー同義語辞書用のテーブルを作る必要があります。ここでは同義語グループを使います。なぜなら同義語辞書のメンテナンスはコストが高いタスクだからです。同義語グループの方が単語ごとに同義語を指定するよりもメンテナンスコストが低いです。
ここではこのテーブルの名前をuser_synonym_groups
にします。
CREATE TABLE user_synonym_groups (
synonyms text[]
);
このテーブルを同義語辞書として使うためにはPGroongaのインデックスが必要です。同義語グループとして使われるsynonyms
にはpgroonga_text_array_term_search_ops_v2
演算子クラスを指定する必要があります。
CREATE INDEX user_synonym_groups_synonyms_index
ON user_synonym_groups
USING pgroonga (synonyms pgroonga_text_array_term_search_ops_v2);
以下はサンプルデータです。
INSERT INTO user_synonym_groups VALUES (ARRAY['pg', 'postgresql']);
この同義語グループデータを使うと、pg
で検索してもpostgresql
で検索しても同じ検索結果になります。pg
で検索するとクエリーはpg OR postgresql
になりまうs.postgresql
で検索してもクエリーはpg OR postgresql
になります。
これらの同義語辞書を使って検索するためにpgroonga_query_expand
関数を2回使います。
最初のpgroonga_query_expand()
はユーザー同義語辞書を使います。
SELECT
pgroonga_query_expand(
'user_synonym_groups',
'synonyms',
'synonyms',
'QUERY'
);
クエリーにpg
を使った場合の例です。
SELECT
pgroonga_query_expand(
'user_synonym_groups',
'synonyms',
'synonyms',
'pg'
);
-- pgroonga_query_expand
-- ------------------------
-- ((pg) OR (postgresql))
-- (1 row)
pg
もpostgresql
も検索されます。
2つめのpgroonga_query_expand()
は1つめのpgroonga_query_expand()
の結果に対してシステム同義語辞書を使います。
SELECT
pgroonga_query_expand(
'system_thesaurus',
'term',
'synonyms',
pgroonga_query_expand(
'user_synonym_groups',
'synonyms',
'synonyms',
'QUERY'
)
);
ユーザー同義語辞書にもうひとつ同義語グループを追加します。
INSERT INTO user_synonym_groups VALUES (ARRAY['on-line', 'online']);
新しく追加した同義語グループを確認しましょう。
SELECT
pgroonga_query_expand(
'user_synonym_groups',
'synonyms',
'synonyms',
'on-line'
);
-- pgroonga_query_expand
-- -------------------------
-- ((on-line) OR (online))
-- (1 row)
クエリーにon-line
を指定してシステム同義語辞書とユーザー同義語辞書を両方使ってみましょう。
SELECT
pgroonga_query_expand(
'system_thesaurus',
'term',
'synonyms',
pgroonga_query_expand(
'user_synonym_groups',
'synonyms',
'synonyms',
'on-line'
)
);
-- pgroonga_query_expand
-- --------------------------------------------------
-- ((on-line) OR (((>-0.2オンライン) OR (online))))
-- (1 row)
このSELECT
は次のように動きます。
on-line
はユーザー同義語辞書でon-line OR online
に展開されます:on-line
-> ((on-line)) OR (online))
online
はシステム同義語辞書で>-0.2オンライン OR online
に展開されます:((on-line)) OR (online))
-> ((on-line) OR (((>-0.2オンライン) OR (online))))
>-0.2オンライン
の>-0.2
はオンライン
の重みを調整しています。この場合、重みは0.8
(1 - 0.2
)になります。
全文検索でこれらの同義語辞書を使ってみましょう。
CREATE TABLE memos (
content text
);
INSERT INTO memos VALUES ('Online conference is easy to join');
INSERT INTO memos VALUES ('On-line conference is easy to join');
INSERT INTO memos VALUES ('オンライン conference is easy to join');
CREATE INDEX memos_content_index ON memos USING pgroonga (content);
-- For ensuring using index
SET enable_seqscan = no;
SELECT content, pgroonga_score(tableoid, ctid) AS score
FROM memos
WHERE
content &@~
pgroonga_query_expand(
'system_thesaurus',
'term',
'synonyms',
pgroonga_query_expand(
'user_synonym_groups',
'synonyms',
'synonyms',
'on-line'
)
);
-- content | score
-- ---------------------------------------+-------------------
-- On-line conference is easy to join | 1
-- オンライン conference is easy to join | 0.800000011920929
-- Online conference is easy to join | 1
-- (3 rows)