4

このようなユーザーのコレクションがあるとしましょう:-

{
  "_id" : "1234",
  "Name" : "John",
  "OS" : "5.1",
  "Groups" : [{
      "_id" : "A",
      "Name" : "Group A"
    }, {
      "_id" : "C",
      "Name" : "Group C"
    }]
}

そして、私はこのようなイベントのコレクションを持っています:-

{
  "_id" : "15342",
  "Event" : "VIEW",
  "UserId" : "1234"
}

「UserId」を発行してカウントオフできるので、mapreduceを使用してユーザーごとのイベントのカウントを計算できますが、ここで実行したいのは、グループごとにイベントをカウントすることです。

イベントドキュメントに「Groups」配列がある場合、これは簡単ですが、そうではありません。これは単なる例であり、実際のアプリケーションははるかに複雑であり、すべてのデータを複製したくありません。イベントドキュメントに。

http://tebros.com/2011/07/using-mongodb-mapreduce-to-join-2-collections/で例を見ましたが、値を集計しているため、この状況でどのように適用されるかわかりません。 2つの場所から...私が本当にやりたいのはルックアップを実行することだけです。

SQLでは、フラット化されたUserGroupテーブルをイベントテーブルに結合し、GROUPBYUserGroup.GroupNameだけを使用します。

mapreduceの複数のパスに満足しています...UserIdで{"_id": "1234"、 "count":9}のようなものにカウントする最初のパスですが、次のパスでスタックします...含める方法グループID

私が検討したいくつかの潜在的なアプローチ:-

  • イベントドキュメントにグループ情報を含める(実行不可能)
  • ユーザーコレクションに「参加」する方法、またはマップ関数内からユーザーグループを検索する方法を検討して、グループIDも発行できるようにします(これを行う方法がわかりません)。
  • イベントとユーザーコレクションを「結合」して、mapreduceを実行できる3番目のコレクションにする方法を検討します

何が可能で、それぞれのアプローチの利点/問題は何ですか?

4

1 に答える 1

1

3番目のアプローチは次の方法です。

イベントとユーザーコレクションを「結合」して、mapreduceを実行できる3番目のコレクションにする方法を検討します

これを行うにはJ、map-reduceに必要な「結合された」データを使用して新しいコレクションを作成する必要があります。これに使用できる戦略はいくつかあります。

  1. アプリケーションを更新Jして、通常の業務で挿入/更新します。これは、MRを非常に頻繁に実行し、最新のデータを使用する必要がある場合に最適です。これにより、コードが大幅に複雑になる可能性があります。実装の観点からは、これを直接(に書き込むことによってJ)または間接的に(ログコレクションに変更を書き込んでからL「新しい」変更をに適用することによって)行うことができますJ。ログ収集アプローチを選択する場合は、何が変更されたかを判断するための戦略が必要になります。一般的なものは2つあります。最高水準点(またはタイムスタンプに基づく_id)と、findAndModifyコマンドでキューとしてログコレクションを使用する方法です。

  2. Jバッチモードで作成/更新します。これは、上記の戦略からの複数の更新がパフォーマンスに影響を与える高性能システムの場合に行う方法です。これは、MRを頻繁に実行する必要がない場合や、最新のデータ精度を保証する必要がない場合にも使用できます。

(2)を使用する場合は、参加する必要のあるコレクション内のドキュメントを反復処理する必要があります。ご存知のとおり、Mongomap-reduceはここでは役に立ちません。これを行うには多くの可能な方法があります。

  1. ドキュメントが少なく、ドキュメントが小さい場合は、DBに直接接続してDBの外部で反復処理できます。

  2. (1)できない場合は、を使用してDB内で反復処理できますdb.eval()。ドキュメントの数が少なくない場合は、デフォルトでブロックされているように使用nolock: trueしてください。db.evalこれは通常、非常に大きなドキュメントセットを処理する傾向があり、ネットワーク上でそれらを移動する余裕がないため、私が選択する戦略です。

  3. (1)実行できず、(2)実行したくない場合は、一時DBを使用してコレクションを別のノードに複製できます。Mongoには、このための便利なcloneCollectionコマンドがあります。DBが認証を必要とする場合、これは機能しないことに注意してください(理由を聞かないでください。これは、奇妙な10genの設計上の選択です)。その場合は、mongodumpとを使用できますmongorestore。新しいDBのローカルデータを取得したら、適切と思われるデータをパーティに含めることができます。MRを完了すると、本番DBの結果コレクションを更新できます。この戦略は、本番レプリカセットをロードしないように、前処理が多い1回限りのmap-reduce操作に使用します。

幸運を!

于 2012-09-03T00:40:34.963 に答える