web-dev-qa-db-ja.com

elasticsearch v.s.アプリケーションをフィルタリングするためのMongoDB

この質問は、実験と実装の詳細を掘り下げる前に、アーキテクチャを選択することに関するものです。 elasticsearch v.sのスケーラビリティとパフォーマンスの観点からの適合性についてです。 MongoDB、やや特定の目的のため。

仮説的には、フィールドと値を持つデータオブジェクトを保存し、オブジェクトのその本体のクエリを許可します。したがって、アドホックに選択されたフィールドに従ってオブジェクトのサブセットをフィルタリングすることは、おそらく両方に適したものです。

私のアプリケーションは、基準に従ってオブジェクトを選択することを中心に展開します。別の言い方をすれば、複数のフィールドで同時にフィルタリングすることでオブジェクトを選択します。クエリフィルタリングの基準は通常1〜5のフィールドで構成され、場合によってはそれ以上になります。一方、フィルターとして選択されるフィールドは、はるかに多くのフィールドのサブセットになります。 20個のフィールド名が存在することを想像してください。各クエリは、20個のフィールド全体からオブジェクトをフィルタリングする試みです(20個のフィールド名が存在する可能性があります。この数値を使用して、個別のクエリでフィルタとして使用されるフィールドへのフィールド)。フィルタリングは、選択されたフィールドの存在、およびフィールド値によって可能です。フィールドAを持ち、フィールドBがxとyの間にあり、フィールドCがwと等しいオブジェクトを除外します。

私のアプリケーションは、この種のフィルタリングを継続的に実行しますが、どのフィールドがいつフィルタリングに使用されるかに関しては、定数はまったくないか、ほとんどありません。 elasticsearchではおそらくインデックスを定義する必要がありますが、インデックスがなくても速度はMongoDBと同等です。

データがストアに入ると、それに関する特別な詳細はありません。オブジェクトは、挿入された後はほとんど変更されません。おそらく古いオブジェクトをドロップする必要があります。両方のデータストアが、内部的に、またはアプリケーションがクエリを作成することによって、削除の期限切れをサポートすると仮定したいと思います。 (あまり頻繁に、特定のクエリに適合するオブジェクトも同様に削除する必要があります)。

どう思いますか?そして、あなたはこの側面を実験しましたか?

この種のタスクに対する2つのデータストアのパフォーマンスとスケーラビリティに興味があります。これは一種の建築設計上の質問であり、十分に考えられた提案のデモンストレーションとして、店舗固有のオプションまたはそれを適切に設計するためのクエリの基礎の詳細を歓迎します。

ありがとう!

155
matanster

まず、重要な違いがあります。MongoDBは汎用データベースであり、ElasticsearchはLuceneが支援する分散テキスト検索エンジンです。人々は、Elasticsearchを汎用データベースとして使用することについて話してきましたが、それが元の設計ではないことを知っています。汎用のNoSQLデータベースと検索エンジンは統合に向けられていると思いますが、現状では、2つはまったく異なる2つのキャンプから来ています。

私の会社ではMongoDBとElasticsearchの両方を使用しています。データをMongoDBに保存し、Elasticsearchを全文検索機能専用に使用しています。 Elasticに照会する必要があるmongoデータフィールドのサブセットのみを送信します。私たちのユースケースは、Mongoデータが常に変化するという点であなたと異なります:レコードまたはレコードのフィールドのサブセットを1日に数回更新でき、これによりそのレコードのエラスティックへの再インデックス付けを呼び出すことができます。その理由だけでも、唯一のデータストアとしてエラスティックを使用することは、選択フィールドを更新できないため、私たちにとっては良い選択肢ではありません。ドキュメント全体のインデックスを再作成する必要があります。これは弾力的な制限ではなく、これがElasticの背後にある基礎となる検索エンジンであるLuceneの仕組みです。あなたの場合、保存されたレコードは変更されないという事実により、その選択をする必要がなくなります。そうは言っても、データの安全性が懸念される場合は、Elasticsearchをデータの唯一のストレージメカニズムとして使用することをもう一度考えます。ある時点でそこに到達するかもしれませんが、まだそこにあるかどうかはわかりません。

速度に関しては、Elastic/LuceneはMongoのクエリ速度と同等であるだけでなく、「どのフィールドがいつでもフィルタリングに使用されるという点でほとんど一定ではない」場合には、特にデータセットが大きくなると、より速くなります。違いは、基礎となるクエリの実装にあります。

  • Elastic/Luceneは Vector Space Modelinverted indexsInformation Retrieval に使用します。これはレコードの類似性をクエリと比較する非常に効率的な方法です。 Elastic/Luceneをクエリすると、すでに答えがわかっています。そのほとんどの作業は、クエリ用語に一致する可能性が最も高いものによって結果をランク付けすることにあります。これは重要なポイントです。データベースとは対照的に、検索エンジンは正確な結果を保証することはできません。クエリにどれだけ近いかによって結果をランク付けします。ほとんどの場合、結果はほぼ正確になります。
  • Mongoのアプローチは、より汎用的なデータストアのアプローチです。 JSONドキュメントを相互に比較します。あらゆる方法で優れたパフォーマンスを引き出すことができますが、実行するクエリに一致するようにインデックスを慎重に作成する必要があります。具体的には、クエリの対象となる複数のフィールドがある場合、 複合キー を慎重に作成して、可能な限り高速にクエリされるデータセットを削減する必要があります。例えば。最初のキーでデータセットの大部分をフィルタリングし、2番目のキーで残りのデータをさらにフィルタリングする必要があります。クエリが定義されたインデックスのキーとキーの順序と一致しない場合、パフォーマンスはかなり低下します。一方、Mongoは真のデータベースであるため、精度が必要なものである場合は、Mongoが提供する答えがすぐに見つかります。

古いレコードを期限切れにするために、ElasticにはTTL機能が組み込まれています。 Mongoはバージョン2.2の時点でそれを導入したばかりだと思います。

予想されるデータサイズ、トランザクション、精度、フィルターの外観など、他の要件がわからないため、具体的な推奨事項を作成することは困難です。うまくいけば、ここから始めましょう。

352
gstathis