0

すべてのユーザー (コレクション内) のアクティビティを合計する非常に大きな集計があります。この集計は、何百万もの結果 (各ユーザー アクティビティ) を返します。この形式で:

 Array ( [_id] => Array ( [user] =>
      MongoId Object ( [$id] => 52050d48e654f6342c002d42 )
        [send] => 1
        [open] => 1
        [click] => 2 )

ここで、いくつかのことを行う必要があります。

  • これらの結果でユーザーを更新します (既存の値を増やします)
  • 更新後、各ユーザーの平均を計算します (開封 / 送信)
  • 各平均を数値と比較し、結果に基づいてユーザーにフラグを追加しますか?

それらをループして一度にそれぞれ更新することなく、集約からのこれらの結果でユーザーを更新するための良いアプローチはどのようになるでしょうか?

4

1 に答える 1

0

私が正しく理解していれば、あなたが共有した結果の例:

{
  user: ObjectId("52050d48e654f6342c002d42"),
  send: 1,
  open: 1,
  click: 2
}

...次のことを行う必要があります。

  • そのユーザーのsendopenフィールドを1それぞれ ずつ増やします。
  • ポスト インクリメントopen/send比率 (保存されていない) を何らかの値と比較し、その比較の結果に基づいてユーザー ドキュメントにブール フラグを設定します。

せいぜい、同様の更新を受け取るユーザーを事前に集約し、値の配列にある複数ドキュメントの更新を発行できると思います。ただし、これには依然として MongoDB が各ユーザーに対して個別にクエリを実行する必要があります。配列引数のサイズには制限がありますが、この戦略の主な利点は、ドライバーとサーバー間で送信する操作が少なくなり、単一の GLE (最後のエラーを取得する) 応答を受け取ることです。_id$in$in

open/比率のsend計算は、すべてのドキュメントからこれらのフィールドを取得する必要があるため、よりトリッキーになります。更新手順の後、ユーザー コレクションに対して 2 番目の集計を発行し、$divide両方のフィールドで使用してその値を計算できる場合があります。その後、商とその他の値を比較演算子で使用できます。これにより、ユーザー ID とブール値のみを含む集計結果を作成できます。そこからさらにドライバーから update ステートメントを発行する必要がありますが、フラグ フィールドに可能な値は 2 つしかないため、それらを複数ドキュメントの更新にグループ化する方がはるかに簡単です。

flag フィールドを常に存在するブール値にすることを強くお勧めします。これにより、新しいフィールドを作成することを心配せずに値を変更でき、割り当てられたスペースを超えた場合にドキュメントをディスクに移動する必要がなくなります。可能な限り、インプレース更新を目指す必要があります。

最後に、PHP ドライバーで検討すべきもう 1 つのオプションは、更新操作の書き込みに関する問題です。ゼロの書き込み懸念を使用すると、エラー応答を待たずに MongoDB に更新をできるだけ速く送信できるため、(エラー チェックを犠牲にして) ある程度のパフォーマンスを得ることができます。

于 2013-08-30T15:08:21.853 に答える