1

map/reduce について、また、それが私が達成しようとしているタスクに適しているかどうかについて質問があります。まだ設計段階なので、必要に応じてデータの構造を変更できます。

次のような 2 つのドキュメントがあるとします。

{ "_id" : ObjectId( "50231b4f8be6e5f1f2e7e24g" ),
  "customer" : "50bac36bb4e54678170002e6",
  "display" : "Motorola Canopy 100",
  "description" : "a radio" }

{ "_id" : ObjectId( "50232fac8be6e4f1f2e7e259" ),
  "display" : "Motorola POE",
  "description" : "a power injector",
  "device" : "50231b4f8be6e4f1f2e7e24g" }

あるドキュメントには顧客 ID 参照 (「customer」: 「50bac36bb4e54678170002e6」) があり、別のドキュメントにはデバイス ID 参照 (「device」: 「50231b4f8be6e4f1f2e7e24g」) があります。これらのドキュメントは両方とも、ある種のデバイスを表しています。デバイスは、顧客に関連付けられる (別名、割り当てられる) か、別のデバイスに関連付けられます。たとえば、顧客がラジオを受け取り、それがそのように割り当てられますが、パワー インジェクタは顧客ではなく、ラジオ自体に割り当てられます。これを行ったのは、デバイス間の運用上の依存関係をよりよく理解できるようにするためです。この階層的な関連付けパターンを維持することは有用であり、可能であれば維持したいと考えています。

現在、最初にすべてのデバイスを検索し、次に見つかった各デバイスに対して、関連するデバイスを探す別のクエリを実行する一連のクエリを実行しています。これは、特定のデバイスへの関連付けがある限り深く実行できる再帰的な操作です。

この問題が map/reduce 操作に適しているかどうかを知りたいです。現在の再帰的操作に固執する必要がありますか、それともこれは map/reduce に適していますか?

編集 1

コメントで提起された質問からのさらなる明確化:

  1. これらの文書がすべて同じコレクションにあるというのは本当ですか? はい 単一の「デバイス」コレクションがあります。ただし、顧客 ID は別のコレクションのものです。ただし、このクエリでは、その ID のみを使用して、デバイス コレクションからの結果をグループ化します。SQL用語を借りるための「結合」は行われず、必要もありません。顧客キーとデバイス キーは、並べ替えが必要な属性と考えてください。
  2. また、「すべてのデバイスを見つける」ためにクエリを実行すると言います。「顧客 ID を指定してすべてのデバイスを検索する」ということですか? はい: 実行される最初のクエリは、キーである顧客 ID に基づいています。基本的には次のようになります: db.devices.find({"customer" : "50bac36bb4e54678170002e6"}). 次に、その結​​果を取得して反復処理し、ストレートな JavaScript を使用してハッシュをソートし、サブクエリを起動します。次に、実行する新しいクエリがいくつか残っています。基本的に、最初のクエリでキャプチャされたすべての _id は、次のようなものでクエリされます。そのクエリは、最初のクエリで発見されなかった新しいドキュメントを生成します。db.devices.find で新しい結果が得られなくなるまで、このサブクエリの手順を続けます。次に、これらの結果に対してさらに JavaScript を実行し、それらを最初の結果にマージして、ハッシュ ツリーを構築します。それが私がツリーを構築する方法を知っている方法です。
  3. すべてのデバイスが 1 人の顧客に「アップ」するというのは本当ですか? はい
  4. デバイスが複数の親デバイスまたは顧客に属する可能性はありますか? いいえ
4

2 に答える 2

3

MapReduce は、依存関係を持たないドキュメントで最適に機能します。データ構造が有向非巡回グラフ (DAG) であり、各顧客がルート ノードであり、各デバイスが複数の親ノードを持つ場合。Map/Reduce は、依存関係があるため、ほとんどの DAG 操作に計算上あまり適していません。

ただし、データはツリー状 (複数の親ではない)であるため、MongoDB docs example のように祖先の配列を追加できます。この場合、MR は一部の操作に適している可能性があります。

あなたのクエリ戦略を理解していれば、各再帰レベルの内部ループで多くのクエリ操作を実行する効率が心配です。これを支援するために、理想的には「デバイス」は文字列ではなく ObjectId タイプである必要があり、インデックスが付けられている必要があります。インデックス作成の代わりに、この MongoDB docs example に従って、子 ObjectId を子参照として保存することもできます。いずれの場合も、再帰レベルごとに MR または "$group" 集計操作を実行すると役立つ可能性がありますが、ほとんどの場合、計算を DB クライアントから DB サーバーにシフトするだけではないかと思います。

于 2013-01-03T06:25:40.203 に答える
1

ここでは map/reduce が良い解決策だとは思いません。データが相互に依存しており、同時実行性が無効になるからです。または、 dbRefを使用して関連デバイスを埋め込み、関連デバイス ドキュメントから直接アクセスできるようにすることもできます。

于 2013-01-03T02:53:57.697 に答える