Database Reference
In-Depth Information
Finally, we iterate through each of the ads and check it using the
ad_is_acceptable
function.
Here's our
ad_iterator
generator:
def
def
ad_iterator
(
ads
):
'''Find available ads, sorted by ecpm, with random sort for ties'''
ecpm_groups
=
groupby
(
ads
,
key
=
lambda
lambda
ad
:
ad
[
'ecpm'
])
for
for
ecpm
,
ad_group
iin
ecpm_groups
:
ad_group
=
list
(
ad_group
)
shuffle
(
ad_group
)
for
for
ad
iin
ad_group
:
yield
yield
ad
This generator yields the ads in an order that both maximizes profitability and randomly
shuffles ads of the same eCPM. Finally, here's our ad filter
ad_is_acceptable
:
def
def
ad_is_acceptable
(
ad
,
profile
):
'''Returns False if the user has seen the ad today'''
threshold
=
datetime
.
utcnow
()
-
timedelta
(
days
=
1
)
for
for
event
iin
reversed
(
profile
[
'impressions'
]):
iif
event
[
'timestamp'
]
<
threshold
:
break
break
iif
event
[
'detail'
][
'ad_unit_id'
]
==
ad
[
'ad_unit_id'
]:
return
return
False
return
return
True
This function examines all the user's ad impressions for the current day and rejects an ad that
has been displayed to that user.
In order to retrieve the user profile with the lowest latency possible, there needs to be an index
on the
_id
field, which MongoDB supplies by default.
Sharding
When sharding the
ad.user
collection, choosing the
_id
field as a shard key allows Mon-
goDB to route queries and updates to the user profile:
>>>
>>>
db
.
command
(
'shardcollection'
,
'dbname.ads.ad.user'
, {
...
...
'key'
: {
'_id'
:
1
} })
{ "collectionsharded": "dbname.ads.ad.user", "ok": 1 }