OK, jeg synes, du skal opdele dette i de grundlæggende "varianter".
Du har to objekter i "entity"-stil:
User
Campaign
Du har ét "mapping"-stil objekt:
UserCampaign
Du har et objekt i "transaktionel"-stil:
Click
Trin 1:enhed
Lad os starte med de nemme:User
&Campaign
. Disse er virkelig to separate objekter, ingen af dem afhænger virkelig af den anden for sin eksistens. Der er heller ingen implicit arvegang mellem de to:Brugere tilhører ikke kampagner, og kampagner tilhører heller ikke brugere.
Når du har to objekter på øverste niveau som dette, tjener de generelt deres egen samling. Så du vil have en Users
samling og en Camapaigns
samling.
Trin 2:kortlægning
UserCampaign
bruges i øjeblikket til at repræsentere en N-til-M mapping. Nu, generelt, når du har en N-til-1 mapping, kan du sætte N inde i 1'eren. Men med N-til-M mapping, skal du generelt "vælge en side".
I teorien kan du gøre et af følgende:
- Læg en liste over
Campaign ID
s inde i hverUser
- Læg en liste over
Users ID
s inde i hverCampaign
Personligt ville jeg gøre #1. Du har sandsynligvis langt flere brugere, som kampagner, og du vil sandsynligvis placere arrayet, hvor det bliver kortere.
Trin 3:Transaktions
Clicks er virkelig et helt andet udyr. I objekttermer kunne du tænke følgende:Click
"tilhører" en User
, Click
"tilhører" en Campaign
. Så i teorien kan du bare gemme klik er en del af et af disse objekter. Det er nemt at tro, at klik hører under Brugere eller kampagner.
Men hvis du virkelig graver dybere, er ovenstående forenkling virkelig mangelfuld. I dit system, Click
er virkelig et centralt objekt. Faktisk kan du endda sige, at brugere og kampagner egentlig bare er "associeret med" klikket.
Tag et kig på de spørgsmål/forespørgsler, du stiller. Alle disse spørgsmål er faktisk centreret omkring klik. Brugere og kampagner er ikke det centrale objekt i dine data, det er klik.
Derudover vil klik være de mest rigelige data i dit system. Du vil få langt flere klik end noget andet.
Dette er det største problem, når man designer et skema til data som dette. Nogle gange har du brug for at skubbe "forældre" objekter væk, når de ikke er det vigtigste. Forestil dig at bygge et simpelt e-handelssystem. Det er tydeligt, at orders
ville "tilhøre" users
, men orders
er så central i systemet, at det bliver et "top-niveau" objekt.
Afslutter det
Du vil sandsynligvis have tre samlinger:
- Bruger -> har en liste over kampagne._id
- Kampagne
- Klik -> indeholder user._id, campaign._id
Dette skulle opfylde alle dine forespørgselsbehov:
Se oplysningerne fra hvert klik som IP, Referer, OS osv.
db.clicks.find()
Se, hvor mange klik der kommer fra X IP, X Referer, X OS
db.clicks.group()
eller kør en Map-Reduce.
Knyt hvert klik til en bruger og en kampagne
db.clicks.find({user_id : blah})
Det er også muligt at skubbe klik-id'er ind i både brugere og kampagner (hvis det giver mening).
Bemærk venligst, at hvis du har mange og mange klik, bliver du virkelig nødt til at analysere de forespørgsler, du kører mest. Du kan ikke indeksere hvert felt, så du vil ofte køre Map-Reduces for at "rulle op" dataene for disse forespørgsler.