1

複数の Web サイトがあり、各 Web サイトには、追跡したい複数のイベントを「トリガー」する訪問者がいます。すべてのWebサイトからのこれらのイベントのログがあり、各イベントにはWebサイトID、イベント名、およびイベントを実行したユーザーIDが含まれています(簡単にするために、それだけだとしましょう)。

要求事項:

  1. Web サイト ID とイベント名ごとに、何人のユニーク ユーザーがそれを取得したかを取得できます。
  2. これは、日付範囲もサポートする必要があります (範囲内の個別のユニークな訪問者)。

次のデータモデルを使用して、「website-id」ごとにコレクションを作成することを考えていました(例として):

collection ev_{websiteId}:
[
    {
        _id: "error"
        dailyStats: [
            {
                _id: 20121005 <-- (yyyyMMdd int, should be indexed!)
                hits: 5
                users: [ 
                         {
                            _id: 1, <-- should be indexed!
                            hits: 1
                         }, 
                         {
                            _id: 2
                            hits: 3
                         },
                         {
                            _id: 3,
                            hits: 1
                         }
                ]
            },
            {
                _id: 20121004 
                hits: 8
                users: [ 
                         {
                            _id: 1,
                            hits: 2
                         }, 
                         {
                            _id: 2
                            hits: 3
                         },
                         {
                            _id: 3,
                            hits: 3
                         }
                ]
            },
        ]
    },
    {
        _id: "pageViews"
        dailyStats: [
            {
                _id: 20121005 
                hits: 500
                users: [ 
                         {
                            _id: 1, 
                            hits: 100
                         }, 
                         {
                            _id: 2
                            hits: 300
                         },
                         {
                            _id: 3,
                            hits: 100
                         }
                ]
            },
            {
                _id: 20121004
                hits: 800
                users: [ 
                         {
                            _id: 1, 
                            hits: 200
                         }, 
                         {
                            _id: 2
                            hits: 300
                         },
                         {
                            _id: 3,
                            hits: 300
                         }
                ]
            },
        ]
    },
]

イベント ID を保持するために _id を使用しています。私は、dailyStats._id を使用して、それが発生したときに保持しています (yyyyMMdd 形式の整数)。ユーザーの一意の ID ハッシュを表すために、dailySattes.users._id を使用しています。

一意のユーザーを取得するには、基本的に、指定された日付範囲ごとに、配列内の個別のカウント数のアイテムを実行 (mapreduce?) できる必要があります (日付範囲を yyyyMMdd に変換します)。

私の質問:

  1. このデータモデルはあなたにとって理にかなっていますか? このモデルのスケーラビリティが長期にわたって懸念されます (あるクライアントで 1 日あたりのユニーク ビジター数が多いと、ドキュメントが膨大になります)。_id < [yyyyMMdd としての日付] までに、dailyStats ドキュメントを削除することを考えていました。このようにして、ドキュメントのサイズを適切な数に保つことができますが、それでも制限があります。
  2. まだ作成されていない場合はdailyStatsも作成し、まだ作成されていない場合はユーザーを追加し、両方の「ヒット」プロパティをインクリメントする「upsert」を実行する簡単な方法はありますか?
  3. マップリデュースはどうですか?どのようにアプローチしますか (指定された日付範囲内のすべてのサブドキュメントの users._id で個別に実行する必要があります)? 新しい集計フレームワークを使用した簡単な方法はありますか?

ところで - 一意の訪問者を解決する別のオプションは、Redis ビットマップを使用することですが、複数のデータ ストレージを保持する価値があるかどうかはわかりません (メンテナンスに関して)。

4

1 に答える 1

1

上記の現在のアーキテクチャに関するコメントはほとんどありません。

スケーラビリティと実際に実行している事前集計の量について指摘されているので、少し心配です。

メトリックを実行するときに使用したMongoインスタンスのほとんどは、あなたが指摘したものと同様のケースですが、実際には、単一のドキュメントを更新し、そのさまざまな部分をアップサートすることに大きく依存しているようです。少しロックを引き起こします。

私は別の道を提案するかもしれません。それは、Mongoがメトリクスの実行について彼らと話しているときにさえ提案するものです。あなたが探している構造をすでに持っているので、私は次の線に沿って何かを作成します:

{
  "_id":"20121005_siteKey_page",
  "hits":512,
  "users":[
   {
     "uid":5, 
     "hits":512,
   }
}

このようにして、ドキュメントのサイズを、すばやくアップサートを実行するのに合理的なサイズに制限します。ここから、mapreduceジョブをバッチで実行して、探しているものをさらに拡張できます。

それはあなたの最終目標にも依存します、あなたはリアルタイムの測定基準を提供しようとしていますか?どのような粒度を取得しようとしていますか?Redisマップは、少なくとも見たいものかもしれません。すばらしい記事はこちらです。

とにかく、解決するのは楽しい問題です:)

これがお役に立てば幸いです。

于 2012-10-24T13:14:11.487 に答える