1

このスキーマを使用して Mongodb にヒットのコレクションを保存しています: { userid: ... date: ... }

2 つの日付の間のユニークな訪問者 (これらの日付の間にヒットした異なるユーザー ID を持つ訪問者) を計算したレポートを表示したいと考えています。

出力例:

訪問者数: ... ヒット数: ...

コレクションのサイズは約 1M レコードです。

私の最初のアイデアは、増分 mapreduce を実行して、日ごとの集計値を計算することです。そして、その日に 2 回目の mapreduce を実行して、最終結果を出力します。

問題は、レポートで日付の範囲を選択すると、正しいユニーク ユーザー数を計算できないことです。

日別の集計値の例: 1 日目: 1 人のユニーク ユーザー 2 日目: 2 人のユニーク ユーザー (1 日目に 2 人のユーザーのうち 1 人がヒット)

ユニーク ビジターの合計は 2 日間で 3 ですが、期間全体でユニーク ビジターは 3 ではなく 2 しかありません。

この例で一意の訪問者を計算する効率的な方法はありますか?

4

2 に答える 2

3

この問題は、目的の日付に対して単一の map-reduce を使用することで解決しやすくなる場合があります。最初に 1 日のユニーク ユーザーを集計する (最初のステップ) 代わりに、確認したいすべての日付に対して同じ集計を行うことができます。このようにして、2 番目のステップを完全に回避できます。

これを Map セクションと Reduce セクションに分割するには、次のようにします。

マップ: 目的の時間範囲に記録されたすべてのユーザー ID を検索します

Reduce: 重複したすべてのユーザー ID を削除します

このプロセスが完了すると、その時間範囲の一意の訪問者 (より具体的には一意のユーザー ID) のセットが残るはずです。

別の方法として、map-reduce をまったく必要としない、さらに簡単な方法があります。「distinct」コマンド ( mongoDB の個別のドキュメントを参照) を使用すると、フィールドを選択し、そのフィールドの個別の (一意の) 値のみで満たされた配列を返すことができます。目的の時間範囲内でドキュメントに対して distinct コマンドを使用した場合、その期間のすべてのユーザー ID を含む配列を重複なしで取得できます。

お役に立てれば!

于 2012-08-30T19:53:00.137 に答える
0

これは、バージョン2.2とその集約フレームワークを使用して簡単に行うことができます。

スキーマ{userid: ""、date: ""}を想定し、2つの特定の日付d1とd2を指定すると、これがパイプラインになります。

db.collection.aggregate(
[
    {
        "$match" : {
            "date" : {
                "$gte" : d1,
                "$lte" : d2
            }
        }
    },
    {
        "$group" : {
            "_id" : "$userid",
            "hits" : {
                "$sum" : 1
            }
        }
    },
    {
        "$group" : {
            "_id" : "1",
            "visitors" : {
                "$sum" : 1
            },
            "hits" : {
                "$sum" : "$hits"
            }
        }
    },
    {
        "$project" : {
            "_id" : 0,
            "visitors" : 1,
            "hits" : 1
        }
    }
]
于 2012-08-31T00:53:49.030 に答える