1

どういうわけか、私は自分自身をだまして、データベースでの全文検索の実装を作成してしまいました。データベース内のすべてのエンティティを表すテーブル、すべてのタグを表すテーブル、タグとエンティティの多対多の関係を表すテーブルがあります。

特定のエンティティのすべてのタグ名をグループ化し、それらを文字列に連結するクエリを作成し、それを ts_vector に変換します。そのクエリは次のようになります。

SELECT e.id, to_tsvector(c.publicname || ' ' || string_agg(cv.name, ' '))
FROM categoryvalue cv, entitycategoryvalue ecv, entity e 
WHERE ccv.categoryvalueid = cv.id AND e.id = ecv.entityid
GROUP BY e.id;

クエリは、次のスキーマで結果を返します。

id | to_tsvector
1  | tag_a, tag_b, tag_c
2  | tag_b, tag_d, tag_e

これはまさに私が ts_query と照合したいものです。私はSQLの初心者ですが、作成したクエリの結果で継続的に更新されるテーブルを作成できる方法があるかどうか疑問に思っていますか?

編集:このブログ投稿http://tech.pro/tutorial/1142/building-faceted-search-with-postgresqlで最終的なソリューションとシステムを文書化しました

4

1 に答える 1

2

が欲しいと思いますVIEW

CREATE VIEW my_tsearch_table AS
SELECT e.id, to_tsvector(c.publicname || ' ' || string_agg(cv.name, ' '))
FROM categoryvalue cv, entitycategoryvalue c=ecv, entity e 
WHERE ccv.categoryvalueid = cv.id AND e.id = ecv.celebrityid
GROUP BY e.id;

ただし、ビューにインデックスを追加できないことに注意してください。tsvector検索ごとにこれらすべての を生成するのは非常にコストがかかるため、これは全文検索では問題になる可能性があります。

そのテーブルにインデックスを付ける必要がある場合は、具体化されたビューを探しています。

PostgreSQL は、自動的に維持されるマテリアライズド ビューをサポートしていません。CREATE MATERIALIZED VIEWいくつかのインデックスを追加することはできません。

できることは、通常のテーブル、クエリで作成された通常のビュー、およびいくつかのトリガー関数を使用して、マテリアライズド ビューを手動で維持することです。

ビューに寄与する各テーブルにトリガー関数を追加し、そのトリガー関数によって、そのテーブルに対して行われた更新に基づいてマテリアライズド ビューを更新 (または、必要に応じて挿入、または削除) します。ただし、これを並行環境で正しく行うのは複雑になる可能性があり、ロック順序のデッドロックが発生しやすくなる可能性があります。

トリガーによって維持されるビューに代わる方法は、マテリアライズド ビューが少し時代遅れになるのを受け入れることです。定期的に新しいテーブルを作成し、通常のビューを新しいテーブルにコピーし、必要なインデックスを追加してから、古いマテリアライズド ビュー テーブルを削除し、新しいテーブルの名前を変更して置き換えます。

以下も参照してください。

于 2012-11-08T01:55:04.027 に答える