マルチテナント Web アプリケーションを開発しており、全文検索を追加して、次のことができるようにしたいと考えています。
1) 現在アクセスしているサイトのみを検索する (ただし、すべてのサイトではない)、
2) そのサイトのセクションのみを検索する (たとえば、サイトのブログまたはフォーラムに検索を制限する)、および
3) 単一のフォーラム スレッドを検索するそれだけ。
どのインデックスを追加すればよいのでしょうか?
データベースが巨大であると仮定してください (そのため、たとえば、サイト ID によるインデックス スキャンと、全文検索によるフィルタリングが遅すぎるため)。
次の 3 つのアプローチが考えられます。
3 つのインデックスを作成します。1) サイトごとにすべてをインデックス化するもの。そして 2) サイトごととサイト セクションごとにすべてのインデックスを作成するもの。3) サイトおよびページ ID ごとにすべてをインデックス化するもの。
1 つのインデックスを作成し、[インデックスするテキスト] に「site_<site-id>」、「section_<section-id>」、「page_<page-id>」などのマジック ワードを挿入します。サイト YYY のセクション XX の場合、「site_XX AND section_YYY AND ...」のように検索クエリの前に付けることができます。
新しいサイトまたはサイト セクションの作成時にデータベース インデックスを動的に追加します。
create index dw1_posts__search_site_YYY on dw1_posts using gin(to_tsvector('english', approved_text)) where site_id = 'YYY';
上記の 3 つのアプローチのいずれかが理にかなっていますか? より良い代替手段はありますか?
(詳細: ただし、アプローチ 1 はおそらく不可能ですか? 列のインデックス作成と全文検索のインデックス作成を同時に試みると、構文エラーが発生します。
> create index dw1_posts__search_site
on dw1_posts (site_id)
using gin(to_tsvector('english', approved_text));
ERROR: syntax error at or near "using"
LINE 1: ...dex dw1_posts__search_site on dw1_posts(site_id) using gin(...
^
> create index dw1_posts__search_site
on dw1_posts
using gin(to_tsvector('english', approved_text))
(site_id);
ERROR: syntax error at or near "("
LINE 1: ... using gin(to_tsvector('english', approved_text)) (site_id);
(アプローチ 1が可能であれば、次のようなクエリを実行できます。
select ... from ... where site_id = ... and <full-text-search-column> @@ <query>;
PostgreSQL に最初に site_id をチェックさせ、次に 1 つのインデックスを使用して全文検索列をチェックさせます。) )
/ 詳細の終了。)
更新、1 週間後:代わりにElasticSearchを使用しています。リレーショナル データベース / PostgreSQL では、ファセット検索のスケーラブルなソリューションが存在しないという印象を受けました。また、ElasticSearch との統合は、ここで提案されているアプローチを実装してテストし、微調整するのとほぼ同じくらい簡単なようです。(たとえば、PostgreSQL のステマー/それが何であれ、"section_NNN" を "section" と "NNN" の 2 つの単語に分割し、ページに存在しない単語をインデックス化する可能性があります! このような小さな迷惑な問題を修正するのは難しいです。)