OK, penso che tu debba suddividerlo nelle "varietà" di base.
Hai due oggetti in stile "entità":
User
Campaign
Hai un oggetto in stile "mappatura":
UserCampaign
Hai un oggetto in stile "transazionale":
Click
Passaggio 1:entità
Cominciamo con quelli facili:User
&Campaign
. Questi sono veramente due oggetti separati, nessuno dei due dipende realmente dall'altro per la sua esistenza. Inoltre, non esiste una gerarchia implicita tra i due:gli utenti non appartengono alle campagne, né le campagne appartengono agli utenti.
Quando hai due oggetti di livello superiore come questo, generalmente guadagnano la propria collezione. Quindi vorrai un Users
raccolta e una Camapaigns
raccolta.
Passaggio 2:mappatura
UserCampaign
è attualmente utilizzato per rappresentare una mappatura da N a M. Ora, in generale, quando hai una mappatura da N a 1, puoi inserire la N all'interno di 1. Tuttavia, con la mappatura da N a M, generalmente devi "scegliere un lato".
In teoria, potresti eseguire una delle seguenti operazioni:
- Inserisci un elenco di
Campaign ID
s all'interno di ogniUser
- Inserisci un elenco di
Users ID
s all'interno di ogniCampaign
Personalmente, farei il numero 1. Probabilmente hai molti più utenti che campagne e probabilmente vorrai mettere l'array dove sarà più breve.
Fase 3:transazionale
I clic sono davvero una bestia completamente diversa. In termini oggettivi potresti pensare quanto segue:Clicks
"appartenere a" un User
, Clicks
"appartenere a" una Campaign
. Quindi, in teoria, potresti semplicemente memorizzare i clic che fanno parte di uno di questi oggetti. È facile pensare che i clic appartengano a sotto Utenti o campagne.
Ma se scavi davvero più a fondo, la semplificazione di cui sopra è davvero imperfetta. Nel tuo sistema, Clicks
sono davvero un oggetto centrale. In effetti, potresti persino affermare che Utenti e campagne sono in realtà solo "associati" al clic.
Dai un'occhiata alle domande/domande che stai ponendo. Tutte queste domande sono in realtà incentrate sui clic. Utenti e campagne non sono l'oggetto centrale dei tuoi dati, ma i clic lo sono.
Inoltre, i clic saranno i dati più abbondanti nel tuo sistema. Avrai molti più clic di qualsiasi altra cosa.
Questo è il più grande intoppo quando si progetta uno schema per dati come questo. A volte è necessario spingere via gli oggetti "genitori" quando non sono la cosa più importante. Immagina di costruire un semplice sistema di e-commerce. È chiaro che orders
"appartenerebbe a" users
, ma orders
è così centrale per il sistema che diventerà un oggetto di "livello superiore".
Concludendo
Probabilmente vorrai tre raccolte:
- Utente -> ha un elenco di campaign._id
- Campagna
- Clic -> contiene user._id, campaign._id
Questo dovrebbe soddisfare tutte le tue esigenze di query:
Visualizza le informazioni di ogni clic come IP, Referer, OS, ecc
db.clicks.find()
Scopri quanti clic provengono spesso da X IP, X Referer, X OS
db.clicks.group()
o esegui una riduzione della mappa.
Associa ogni clic con un Utente e una Campagna
db.clicks.find({user_id : blah})
È anche possibile inserire gli ID clic sia negli utenti che nelle campagne (se ha senso).
Tieni presente che se hai moltissimi clic, dovrai davvero analizzare le query che esegui di più. Non puoi indicizzare su ogni campo, quindi spesso vorrai eseguire Map-Reduces per "raggruppare" i dati per queste query.