web-dev-qa-db-ja.com

postgresqlを使用した多言語全文検索

一部の画像でpostgresqlを使用して全文検索を実装しようとしています。画像に関するいくつかの情報をテーブルのjsonフィールドに格納しています。このjsonにはtagsキーがあり、複数の言語があり、それぞれに次のようなタグ(キーワード)が付いています。

"tags": {
    "en": ["blue female", "red female"],
    "es": ["hembra azul", "hembra roja"]
}

現時点では、言語が増えていることを考えると、tsvectorを保存する方法がわかりません。

最初のアイデアの1つは、これらすべてのtsvectorsを1つに連結して、テーブルの列に格納することでした。

2番目のアイデアは、言語ごとに異なる列を作成し、対応するベクトルをその列に格納することです。

どちらが良いでしょうか?おそらく別のより良いアプローチがありますか?

1
melokki

言語ごとに異なる列を使用する必要があります。

主な理由は、言語によってストップワードとステミングルールが異なるためです。そのため、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');
_
0
Laurenz Albe