複数の Web サイトがあり、各 Web サイトには、追跡したい複数のイベントを「トリガー」する訪問者がいます。すべてのWebサイトからのこれらのイベントのログがあり、各イベントにはWebサイトID、イベント名、およびイベントを実行したユーザーIDが含まれています(簡単にするために、それだけだとしましょう)。
要求事項:
- Web サイト ID とイベント名ごとに、何人のユニーク ユーザーがそれを取得したかを取得できます。
- これは、日付範囲もサポートする必要があります (範囲内の個別のユニークな訪問者)。
次のデータモデルを使用して、「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 日あたりのユニーク ビジター数が多いと、ドキュメントが膨大になります)。_id < [yyyyMMdd としての日付] までに、dailyStats ドキュメントを削除することを考えていました。このようにして、ドキュメントのサイズを適切な数に保つことができますが、それでも制限があります。
- まだ作成されていない場合はdailyStatsも作成し、まだ作成されていない場合はユーザーを追加し、両方の「ヒット」プロパティをインクリメントする「upsert」を実行する簡単な方法はありますか?
- マップリデュースはどうですか?どのようにアプローチしますか (指定された日付範囲内のすべてのサブドキュメントの users._id で個別に実行する必要があります)? 新しい集計フレームワークを使用した簡単な方法はありますか?
ところで - 一意の訪問者を解決する別のオプションは、Redis ビットマップを使用することですが、複数のデータ ストレージを保持する価値があるかどうかはわかりません (メンテナンスに関して)。