全文検索を必要とするHerokuでRailsアプリをデプロイする準備をしています。これまで、MySQLとSphinxを使用してVPSで実行してきました。
ただし、HerokuでSphinxまたはSolrを使用する場合は、アドオンに料金を支払う必要があります。
PostgreSQL(Herokuで使用されるDB)には全文検索機能が組み込まれていることに気付きました。
Postgresの全文検索を使用できなかった理由はありますか? Sphinxより遅いのですか、それとも他の大きな制限がありますか?
Postgres vs. Luceneに興味があるなら、なぜ両方ではないのですか? Elasticsearchを一流のインデックスタイプとして統合するPostgresの ZomboDB 拡張機能を確認してください。まだかなり初期のプロジェクトですが、本当に有望に見えます。
(技術的にHerokuでは利用できませんが、まだ見る価値があります。)
開示:私は Websolr および Bonsai Herokuアドオンの共同設立者なので、私の視点はLuceneに少し偏っています。
Postgresの全文検索に関する私の記事は、単純なユースケースではかなり安定しているということですが、Lucene(およびSolrとElasticSearch)がパフォーマンスと機能の両方の面で優れている理由はいくつかあります。
手始めに、 jpountz は質問に対する真に優れた技術的回答を提供します。 なぜSolrはPostgresよりもはるかに高速ですか? 本当にダイジェストするための読み取りのカップル。
また、 最近のRailsCastエピソードについてコメントしました Postgres全文検索とSolrの相対的な長所と短所を比較しました。ここで要約します。
LIKE
演算子よりもはるかに優れています。頭の先から順不同で…
明らかに、Luceneに基づいた専用の検索エンジンの方が良い選択肢だと思います。基本的に、Luceneは、検索の専門知識の事実上のオープンソースリポジトリと考えることができます。
しかし、他のオプションがLIKE
演算子だけである場合、Postgresの全文検索は間違いなく勝利です。
エラスティック検索(1.9)とpostgres FTSを比較する作業を行ったばかりなので、@ gustavodiazjaimesが引用するものよりもやや新しいため、結果を共有する必要があると考えました。
Postgresに対する私の主な懸念は、ファセットが組み込まれていないことでしたが、自分でビルドするのは簡単なことです(Djangoの例):
results = YourModel.objects.filter(vector_search=query)
facets = (results
.values('book')
.annotate(total=Count('book'))
.order_by('book'))
私はpostgres 9.6とelastic-search 1.9を使用しています(Djangoのhaystackを使用)。 16のさまざまなタイプのクエリでのelasticsearchとpostgresの比較を次に示します。
es_times pg_times es_times_faceted pg_times_faceted
0 0.065972 0.000543 0.015538 0.037876
1 0.000292 0.000233 0.005865 0.007130
2 0.000257 0.000229 0.005203 0.002168
3 0.000247 0.000161 0.003052 0.001299
4 0.000276 0.000150 0.002647 0.001167
5 0.000245 0.000151 0.005098 0.001512
6 0.000251 0.000155 0.005317 0.002550
7 0.000331 0.000163 0.005635 0.002202
8 0.000268 0.000168 0.006469 0.002408
9 0.000290 0.000236 0.006167 0.002398
10 0.000364 0.000224 0.005755 0.001846
11 0.000264 0.000182 0.005153 0.001667
12 0.000287 0.000153 0.010218 0.001769
13 0.000264 0.000231 0.005309 0.001586
14 0.000257 0.000195 0.004813 0.001562
15 0.000248 0.000174 0.032146 0.002246
count mean std min 25% 50% 75% max
es_times 16.0 0.004382 0.016424 0.000245 0.000255 0.000266 0.000291 0.065972
pg_times 16.0 0.000209 0.000095 0.000150 0.000160 0.000178 0.000229 0.000543
es_times_faceted 16.0 0.007774 0.007150 0.002647 0.005139 0.005476 0.006242 0.032146
pg_times_faceted 16.0 0.004462 0.009015 0.001167 0.001580 0.002007 0.002400 0.037876
ファセット検索のためにこれらの速度にpostgresを取得するために、SearchVectorFieldを持つフィールドでGINインデックスを使用する必要がありました。これはDjango特定ですが、他のフレームワークも同様のベクトル型を持っていると確信しています。
もう1つの考慮事項は、pg 9.6がフレーズ一致をサポートするようになったことです。これは膨大です。
私の要点は、ほとんどの場合、postgresが次のように優先されることです。
この驚くべき比較を見つけたので、共有したいと思います。
LIKE述語のような索引を作成する時間-なし
PostgreSQL/GIN-40分
スフィンクス検索-6分
Apache Lucene-9分
転置インデックス-高
インデックスストレージLIKE述語-なし
PostgreSQL/GIN-532 MB
Sphinx Search-533 MB
Apache Lucene-1071 MB
転置インデックス-101 MB
クエリ速度LIKE述語-90秒以上
PostgreSQL/GIN-20ミリ秒
Sphinx Search-8ミリ秒
Apache Lucene-80ミリ秒
転置インデックス-40ミリ秒
Postgresの全文検索には、ステミング、ランキング/ブースティング、同義語処理、ファジー検索などの分野で素晴らしい機能がありますが、ファセット検索はサポートされていません。
したがって、Postgresが既にスタックにあり、ファセットを必要としない場合は、Luceneベースのソリューションを探す前に、インデックスの同期を維持し、スムーズなスタックを維持するという非常に大きなメリットを活用してください。アプリは検索に基づいていません。
PostgresqlのFTS関数は成熟しており、検索がかなり高速です。確かに一見の価値があります。