📖
Supabase の PGroonga 全文検索で同義語検索してみる
こちらの記事の続きです。
PGroonga による全文検索で同義語検索できるようにしてみます。
PGroonga のドキュメントを参考に実装していきます。
同義語テーブルとインデックスを作成する
まずは同義語テーブルを作成します。
同義語テーブル作成
CREATE TABLE synonyms (
term text PRIMARY KEY,
synonyms text[]
);
そして、そのテーブルにインデックスを作成します。
同義語テーブル用インデックス作成
CREATE INDEX synonyms_search ON synonyms USING pgroonga (term pgroonga_text_term_search_ops_v2);
テーブルとインデックスの作成ができたら、同義語をテーブルに追加します。
同義語をテーブルに追加
INSERT INTO synonyms (term, synonyms) VALUES ('美術館', ARRAY['美術館', 'ミュージアム']);
INSERT INTO synonyms (term, synonyms) VALUES ('博物館', ARRAY['博物館', 'ミュージアム']);
INSERT INTO synonyms (term, synonyms) VALUES ('ミュージアム', ARRAY['ミュージアム', '美術館', '博物館']);
- 「美術館」で検索したときに「ミュージアム」を含む文章も対象とする
- 「博物館」で検索したときに「ミュージアム」を含む文章も対象とする
- 「ミュージアム」で検索したときに「美術館」「博物館」を含む文章も対象とする
という指定です。
ストアドファンクションを同義語検索対応にする
前回の記事で、WHERE
句の条件に
ft_text &@~ keywords
と指定したところを、
ft_text &@~ pgroonga_query_expand('synonyms', 'term', 'synonyms', keywords)
に書き換えます。
ストアドファンクション同義語検索対応
CREATE OR REPLACE
FUNCTION get_spots(point_latitude double precision, point_longitude double precision, dist_limit int, category_id_number int, keywords text)
RETURNS TABLE (
distance double precision,
category_name text,
title text,
describe text,
latitude double precision,
longitude double precision,
prefecture text,
municipality text
) AS $$
BEGIN
RETURN QUERY
SELECT ((ST_POINT(point_longitude, point_latitude)::geography <-> spot_opendata.location::geography) / 1000) AS distance,
category.category_name,
spot_opendata.title,
spot_opendata.describe,
ST_Y(spot_opendata.location),
ST_X(spot_opendata.location),
spot_opendata.prefecture,
spot_opendata.municipality
FROM spot_opendata
INNER JOIN category ON spot_opendata.category_id = category.id
WHERE
(CASE WHEN dist_limit = -1 AND keywords = '' THEN false ELSE true END)
AND
(CASE WHEN dist_limit = -1 THEN true
ELSE (ST_POINT(point_longitude, point_latitude)::geography <-> spot_opendata.location::geography) <= dist_limit END)
AND
(CASE WHEN category_id_number = -1 THEN true
ELSE category.id = category_id_number END)
AND
(CASE WHEN keywords = '' THEN true
ELSE ft_text &@~ pgroonga_query_expand('synonyms', 'term', 'synonyms', keywords) END)
ORDER BY distance;
END;
$$ LANGUAGE plpgsql;
以上で全文検索が同義語対応になりました。
SQL Editor で確認
SQL Editor で「ミュージアム」を検索してみると、
「美術館」「博物館」もヒットしていることがわかります。
2023/2/1 追記:
続きの記事を書きました。
Discussion