Ответ 1
Хорошо, я думаю, вам нужно разбить это на основные "разновидности".
У вас есть два объекта "entity":
-
User
-
Campaign
У вас есть один объект "mapping":
-
UserCampaign
У вас есть один "транзакционный" -стильный объект:
-
Click
Шаг 1: объект
Начнем с простых: User
и Campaign
. Это действительно два отдельных объекта, ни один из них не зависит от другого для его существования. Там также нет скрытой иерархии между двумя: пользователи не принадлежат к Кампаниям, и Кампании не принадлежат Пользователям.
Когда у вас есть два объекта верхнего уровня, подобные этому, они обычно зарабатывают свою собственную коллекцию. Поэтому вам понадобится коллекция Users
и коллекция Camapaigns
.
Шаг 2: отображение
UserCampaign
в настоящее время используется для отображения N-to-M. Теперь, в общем, когда у вас есть сопоставление N-to-1, вы можете поместить N внутри 1. Однако при сопоставлении N-to-M вам обычно нужно "выбрать сторону".
В теории вы можете сделать одно из следующих действий:
- Поместите список
Campaign ID
внутри каждогоUser
- Поместите список
Users ID
внутри каждогоCampaign
Лично я бы сделал # 1. Вероятно, у вас больше пользователей, чем в кампаниях, и вы, вероятно, захотите разместить массив там, где он будет короче.
Шаг 3: транзакционный
Клики - это совсем другой зверь. В объектных терминах вы можете подумать о следующем: Clicks
"принадлежит" a User
, Clicks
"относятся к" a Campaign
. Таким образом, теоретически, вы можете просто хранить клики, являются частью любого из этих объектов. Легко думать, что клики принадлежат пользователям или кампаниям.
Но если вы действительно копаете глубже, вышеупомянутое упрощение действительно ошибочно. В вашей системе Clicks
действительно являются центральным объектом. Фактически, вы даже можете сказать, что пользователи и кампании действительно просто "связаны с" щелчком.
Взгляните на вопросы/запросы, которые вы задаете. Все эти вопросы фактически сосредоточены вокруг кликов. Пользователи и кампании не являются центральным объектом в ваших данных, клики.
Кроме того, клики будут самыми обильными данными в вашей системе. У вас будет больше кликов, чем что-либо еще.
Это самая большая заминка при разработке схемы для таких данных. Иногда вам нужно отталкивать "родительские" объекты, когда они не самые важные. Представьте себе создание простой системы электронной коммерции. Ясно, что orders
будет "принадлежать" Users
, но orders
является таким центральным для системы, что он станет объектом верхнего уровня.
Обернуть его
Вероятно, вам понадобятся три коллекции:
- Пользователь → имеет список campaign._id
- кампании
- Клики → содержит user._id, campaign._id
Это должно удовлетворять всем вашим запросам:
См. информацию от каждого клика, такого как IP, Referer, OS и т.д.
db.clicks.find()
Посмотрите, сколько часто кликов происходит от X IP, X Referer, X OS
db.clicks.group()
или запустите Map-Reduce.
Свяжите каждый клик с пользователем и кампанией
db.clicks.find({user_id : blah})
Можно также нажать идентификаторы кликов для пользователей и кампаний (если это имеет смысл).
Обратите внимание, что если у вас много и много кликов, вам действительно придется анализировать запросы, которые вы запускаете больше всего. Вы не можете индексировать в каждом поле, так что вы часто захотите запустить Map-Reduces для "свертывания" данных для этих запросов.