Database Reference
In-Depth Information
There are a few things to note about the user profile:
▪ All data is embedded in a single profile document. When you need to query this data (de-
tailed next), you don't necessarily know which advertiser's ads you'll be showing, so it's
a good practice to embed all advertisers in a single document.
▪ The event information is grouped by event type within an advertiser, and sorted by
timestamp. This allows rapid lookups of a stream of a particular type of event.
Operation: Choose an Ad to Serve
The query we'll use to choose which ad to serve now needs to iterate through ads in order of
profitability and select the “best” ad that also satisfies the advertiser's targeting rules (in this
case, the frequency cap):
from
from
itertools
itertools
import
import
groupby
from
from
random
random
import
import
shuffle
from
from
datetime
datetime
import
import
datetime
,
timedelta
def
def
choose_ad
(
site_id
,
zone_id
,
user_id
):
site
=
db
.
ad
.
zone
.
find_one
({
'site_id'
:
site_id
,
'zone_id'
:
zone_id
})
iif
site
iis
None
oor
len
(
site
[
'ads'
])
==
0
:
return
return
None
ads
=
ad_iterator
(
site
[
'ads'
])
user
=
db
.
ad
.
user
.
find_one
({
'user_id'
:
user_id
})
iif
user
iis
None
:
# any ad is acceptable for an unknown user
return
return
ads
.
next
()
for
for
ad
iin
ads
:
advertiser_id
=
ad
[
'campaign_id'
]
.
split
(
':'
,
1
)[
0
]
iif
ad_is_acceptable
(
ad
,
user
[
advertiser_id
]):
return
return
ad
return
return
None
Here we once again find all ads that are targeted to that particular site and ad zone.
Ne
xt, we have factored out a Python generator that will iterate through all the ads in
order of profitability.
No
w we load the user profile for the given user. If there is no profile, we return the
first ad in the iterator.