Bien, creo que debes dividir esto en "variedades" básicas.
Tienes dos objetos de estilo "entidad":
User
Campaign
Tienes un objeto de estilo "asignación":
UserCampaign
Tienes un objeto de estilo "transaccional":
Click
Paso 1:entidad
Comencemos con los fáciles:User
&Campaign
. Estos son verdaderamente dos objetos separados, ninguno depende realmente del otro para su existencia. Tampoco existe una jerarquía implícita entre los dos:los usuarios no pertenecen a las campañas, ni las campañas pertenecen a los usuarios.
Cuando tienes dos objetos de nivel superior como este, generalmente obtienen su propia colección. Así que querrás un Users
colección y una Camapaigns
colección.
Paso 2:mapeo
UserCampaign
se utiliza actualmente para representar un mapeo de N a M. Ahora, en general, cuando tiene una asignación de N a 1, puede colocar la N dentro del 1. Sin embargo, con la asignación de N a M, generalmente tiene que "elegir un lado".
En teoría, podrías hacer una de las siguientes cosas:
- Ponga una lista de
Campaign ID
s dentro de cadaUser
- Poner una lista de
Users ID
s dentro de cadaCampaign
Personalmente, haría el número 1. Probablemente tenga muchos más usuarios que campañas, y probablemente quiera colocar la matriz donde sea más corta.
Paso 3:transaccional
Los clics son realmente una bestia completamente diferente. En términos de objetos, podría pensar lo siguiente:Clicks
"pertenecer a" un User
, Clicks
"pertenecer a" una Campaign
. Entonces, en teoría, podría simplemente almacenar los clics que son parte de cualquiera de estos objetos. Es fácil pensar que los clics pertenecen a debajo Usuarios o Campañas.
Pero si realmente profundiza, la simplificación anterior es realmente defectuosa. En su sistema, Clicks
son realmente un objeto central. De hecho, incluso podría decir que los Usuarios y las Campañas en realidad solo están "asociados con" el clic.
Eche un vistazo a las preguntas / consultas que está haciendo. Todas esas preguntas en realidad se centran en los clics. Los usuarios y las campañas no son el objeto central de sus datos, sino los clics.
Además, los clics serán los datos más abundantes en su sistema. Obtendrá muchos más clics que cualquier otra cosa.
Este es el mayor problema al diseñar un esquema para datos como este. A veces es necesario eliminar los objetos "principales" cuando no son lo más importante. Imagine construir un sistema de comercio electrónico simple. Está claro que orders
"pertenecería a" users
, pero orders
es tan central para el sistema que va a ser un objeto de "nivel superior".
Resumiéndolo
Probablemente querrá tres colecciones:
- Usuario -> tiene una lista de Campaign._id
- Campaña
- Clics -> contiene usuario._id, campaña._id
Esto debería satisfacer todas sus necesidades de consulta:
Vea la información de cada clic como IP, Referer, OS, etc
db.clicks.find()
Vea con qué frecuencia los clics provienen de X IP, X Referer, X OS
db.clicks.group()
o ejecuta un Map-Reduce.
Asociar cada clic con un Usuario y una Campaña
db.clicks.find({user_id : blah})
También es posible insertar ID de clic tanto en usuarios como en campañas (si tiene sentido).
Tenga en cuenta que si tiene muchísimos clics, realmente tendrá que analizar las consultas que ejecuta con más frecuencia. No puede indexar todos los campos, por lo que a menudo querrá ejecutar Map-Reduces para "resumir" los datos de estas consultas.