198

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

仮に、両方ともフィールドと値を持つデータオブジェクトを格納し、オブジェクトのその本体をクエリできるようにします。したがって、おそらく、アドホックに選択されたフィールドに従ってオブジェクトのサブセットを除外することは、両方に適したものです。

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

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

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

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

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

ありがとう!

4

1 に答える 1

425

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

私の会社ではMongoDBとElasticsearchの両方を使用しています。データをMongoDBに保存し、Elasticsearchをその全文検索機能専用に使用します。クエリする必要のあるmongoデータフィールドのサブセットのみをelasticに送信します。私たちのユースケースは、Mongoデータが常に変化するという点であなたのユースケースとは異なります。レコード、またはレコードのフィールドのサブセットは1日に数回更新でき、これにより、そのレコードのエラスティックへのインデックスの再作成が必要になる場合があります。その理由だけで、選択したフィールドを更新できないため、elasticを唯一のデータストアとして使用することは適切なオプションではありません。ドキュメント全体のインデックスを再作成する必要があります。これはエラスティックな制限ではありません。これは、エラスティックの背後にある基盤となる検索エンジンであるLuceneの動作方法です。あなたの場合、レコードが 保存したら変更することで、その選択をする必要がなくなります。そうは言っても、データの安全性が懸念される場合は、Elasticsearchをデータの唯一のストレージメカニズムとして使用することを考え直します。いつかそこに着くかもしれませんが、まだそこにあるかどうかはわかりません。

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

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

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

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

于 2012-10-04T18:22:49.510 に答える