10

3 つのテーブルの組み合わせで構成される postgresql ビューがあります。

create view search_view as 
select u.first_name, u.last_name, a.notes, a.summary, a.search_index 
from user as u, assessor as a, connector as c 
where a.connector_id = c.id and c.user_id = u.id;

ただし、3 つのテーブルのうち 2 つの tsvector フィールドを、ビュー内の 1 つの tsvector フィールドに連結して、4 つのフィールド (1 つのテーブルから 2 つ、別のテーブルから 2 つ) にわたる全文検索を提供する必要があります。

concat 演算子を使用して 2 つの tsvector フィールドを結合できるというドキュメントを読みましたが、これが構文的にどのように見えるか、またこの実装に潜在的な落とし穴があるかどうかはわかりません。

2 つの tsvector フィールドを別々のテーブルからビューに連結するサンプル コードと、これが postgresql ランドでの良い方法か悪い方法かについての解説を探しています。

4

2 に答える 2

1

tsv ベクトルの連結は機能しますが、コメントによると、index はおそらくこの方法では使用されません (専門家ではないため、そうであるかどうかはわかりません)。

SELECT * FROM newsletters
LEFT JOIN campaigns ON newsletters.campaign_id=campaigns.id
WHERE newsletters.tsv || campaigns.tsv @@ to_tsquery(unaccent(?))

これが必要な理由txt1 & txt2 & txt 3は、非常に一般的な使用シナリオのような AND 文字列を検索するためです。検索を単純に分割するOR WHERE campaigns.tsv @@ to_tsquery(unaccent(?)と、両方の tsv 列の 3 つのトークンすべてに一致しようとするが、トークンはいずれかの列にある可能性があるため、これは機能しません。

私が見つけた解決策の 1 つは、table2 が変更されるたびに、トリガーを使用して table1 の tsv 列を挿入および更新することです。 -trigger-with-many-to-manyですが、これは決定的な答えではなく、多くのトリガーを使用するとエラーが発生しやすく、ハッキングされます。

公式ドキュメントといくつかのチュートリアルでは、tsv 列を使用せずに、必要なすべての列をオンザフライで ts ベクトルに連結することも示されています。しかし、オンザフライと tsv 列のアプローチがどれだけ遅いかは不明です。これに関する単一のベンチマークや説明が見つかりません。ドキュメントには、次のように簡単に記載されています。

もう 1 つの利点は、インデックスの一致を確認するために to_tsvector 呼び出しをやり直す必要がないため、検索が高速になることです。(これは、GIN インデックスよりも GiST インデックスを使用する場合に重要です。セクション 12.9 を参照してください。) ただし、式インデックスのアプローチはセットアップが簡単で、tsvector 表現が明示的に格納されないため、必要なディスク容量が少なくて済みます。

このことから私が言えることは、tsv 列はおそらくリソースの浪費であり、物事を複雑にするだけであるということですが、いくつかの具体的な数値を確認できれば幸いです。しかし、このように tsv 列を連結できれば、WHERE 句で連結するのと変わらないと思います。

于 2016-11-15T15:37:09.197 に答える
1

私は同じことを疑問に思っていました。このように複数のテーブルから tsvectors を組み合わせることになっているとは思いません。最善の解決策は次のとおりです。

  1. 各テーブル (ユーザー、評価者、コネクタ) に新しい tsv 列を作成します。
  2. 検索するすべてのテキストで各テーブルの新しい tsv 列を更新します。たとえば、user テーブルでは、first_name 列と last_name 列を連結するすべてのレコードの tsv 列を更新します。
  3. 新しい tsv 列にインデックスを作成します。これは、個々の列にインデックスを付けるよりも高速です
  4. 通常どおりクエリを実行し、使用するインデックスについて Postgres に "考えさせます"。複数のテーブルを含むクエリですべてのインデックスを使用する場合と使用しない場合があります。
  5. ANALYZE および EXPLAIN コマンドを使用して、Postgres が特定のクエリに対して新しいインデックスをどのように利用しているかを調べます。これにより、さらに高速化するための洞察が得られます。

これは少なくとも私のアプローチになります。私は多くの読書をしてきましたが、人々が複数のテーブルのデータを tsvectors に結合していないことがわかりました。実際、これは可能ではないと思います.tsvectorを作成するときに現在のテーブルの列を使用することしかできないかもしれません.

于 2014-04-02T01:02:39.497 に答える