2

タスク: PostgreSQL の複数のテーブルに全文検索を実装します。

たとえば、プロジェクトのテーブル - プロジェクト: 検索する必要がある 2 つのフィールドがあります: タイトルと説明です。このテーブルにインデックスを作成します。

ALTER TABLE public.projects ADD COLUMN search_fts tsvector;
UPDATE public.projects SET search_fts =
to_tsvector(
    coalesce(title, '') ||' '||
    coalesce(description, '') || ' '
);
CREATE INDEX in_projects_idx ON public.projects
  USING gin (search_fts);

検索が簡単になりました:

SELECT
    DISTINCT p.id,
    p.title,
    ts_rank(
        p.search_fts,
        to_tsquery('word1 | word2')
    ) as rank
FROM
    projects p
WHERE
    p.search_fts @@ to_tsquery('word1 | word2')
ORDER BY rank DESC;

洗練。ここで、テーブルとプロジェクト カテゴリ (project_categories) を確認する必要があります。tsvector の作成とフィールド名のテーブルの場合と同様です。検索クエリは次のとおりです。

SELECT
    DISTINCT p.id,
    p.title,
    category.name as categoryName,
    ts_rank(
        (
            coalesce(p.search_fts, '') ||' '||
            coalesce(category.search_fts, '')
        ),
        to_tsquery('word1 | word2 | categoryName')
    ) as rank
FROM
    projects p
LEFT JOIN project_categories category
    ON p.category_id = category.category_id
WHERE
    (
        coalesce(p.search_fts, '') ||' '||
        coalesce(category.search_fts, '')
    ) @@ to_tsquery('word1 | word2 | categoryName')
ORDER BY rank DESC;

より洗練された。現在、プロジェクトに関連する数十のテーブルを 1 対多および多対多で検索する必要があります。

数字の結合が増えています。ますます多くのフィールドに結合します。

実際、質問は正しい方法ですか?この問題をどのように解決しますか?

ビュー付きのバージョンも考えています。たとえば、次のようなリクエストに基づいて構築されています。

(
  SELECT 
      p.id as project_id,
      p.search_fts
  FROM projects p
) UNION ALL (
  SELECT 
      p.id as project_id,
      category.search_fts
  FROM projects p
  JOIN project_categories category
      ON p.category_id = category.category_id
)

最後に、全体のインデックスを取得します。検索する基準。しかし、ビューでは、さまざまな通信オプションに対する多数の要求を組み合わせる必要があります。このオプションに関するあなたの意見に興味があります。

私の英語でごめんなさい。

4

1 に答える 1

3

いくつかのオプションがあります。

  • すべての入力テーブルでトリガーを使用して、テキスト行の対象となるすべてのレコードを組み合わせたサマリーテーブルを維持します。これは、1つ以上のエントリと1つ以上のエントリcustomerがあるような単純な場合に問題なく機能します。これは、単純な連結および結合されたテーブルを使用するように、要約検索テーブルに配置できます。ただし、深くネストされた関係への拡張は不十分であり、ロックと同時実行の問題が発生する可能性があります。phoneaddress|customername|customerid|phone1|phone2|phone3|...|address1|address2|...string_agg

  • 複雑な検索問題を解決するように設計されたApacheSolrのような外部検索システムを使用します。

于 2013-02-24T23:51:24.710 に答える