一部の画像でpostgresqlを使用して全文検索を実装しようとしています。画像に関するいくつかの情報をテーブルのjsonフィールドに格納しています。このjsonにはtags
キーがあり、複数の言語があり、それぞれに次のようなタグ(キーワード)が付いています。
"tags": {
"en": ["blue female", "red female"],
"es": ["hembra azul", "hembra roja"]
}
現時点では、言語が増えていることを考えると、tsvector
を保存する方法がわかりません。
最初のアイデアの1つは、これらすべてのtsvectors
を1つに連結して、テーブルの列に格納することでした。
2番目のアイデアは、言語ごとに異なる列を作成し、対応するベクトルをその列に格納することです。
どちらが良いでしょうか?おそらく別のより良いアプローチがありますか?
言語ごとに異なる列を使用する必要があります。
主な理由は、言語によってストップワードとステミングルールが異なるためです。そのため、to_tsvector('spanish', ...)
を使用してインデックスを作成した場合、to_tsquery('english', ...)
を使用して常に検索できるとは限りません。逆も同様です。
_SELECT to_tsvector('spanish', 'hembra azul') @@ to_tsquery('english', 'hembra');
?column?
----------
f
(1 row)
_
言語ごとに列を作成するのではなく、to_tsvector('english', (tags->'tags'->'en'))
およびto_tsvector('spanish', (tags->'tags'->'es'))
のGINインデックスのみを作成するのがさらに良いでしょう。例えば:
_CREATE TABLE images (
id bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
image bytea NOT NULL,
tags jsonb NOT NULL
);
CREATE INDEX images_tags_en_idx ON images
(to_tsvector('english', (tags->'tags'->'en')));
CREATE INDEX images_tags_es_idx ON images
(to_tsvector('spanish', (tags->'tags'->'es')));
_
次に、最初のインデックスを使用できます
_SELECT * FROM images
WHERE to_tsvector('english', (tags->'tags'->'en'))
@@ to_tsquery('english', 'female');
_