索引布尔表达式
问题背景
广告推荐引擎中,广告主会对广告投放做一下定向要求(比如:性别,年龄,城市等),这就需要通过用户画像特征从广告库里面检索出符合定向要求的广告。
当广告数量少的时候,我们可以迭代每个广告做比对。
Attributes = list<Attribute> // 用户的流量标签,例如:用户的年龄、性别...
for (Ad ad : ads) {
check attributes for each ad. // 对于每一个广告检查是不是符合流量标签,挑选广告.
}
但是这样有个缺点就是随着广告数量增多,比较的次数也会增加,检索的耗时也会随着增加,显然这个不符合业务要求。
索引布尔表达式
基本概念
-
Conjunction,表示一个广告的定向条件,比如:
age ∈ {18-29} ^ region ∈ {SZ};
-
Assignment,表示定向条件中的一个维度,比如:age ∈ {18-29};
-
size (Conjunction),是指 conjunction 中包含非∉ 的Assignment的个数;
原理
我们通过三个广告ad1,ad2,ad3来梳理一下布尔索引的逻辑
ad1: age ∈ {18-29} ^ region ∈ {SZ} ^ net∈ {WIFI} ;
ad2: age ∈ {26-29} ^ region ∈ {SZ} ^ gender∈ {F};
ad3: age ∈ {18-29} ^ region ∈ {SZ};
ad4: app ∉ {3301} ^ net∈ {WIFI}
我们可以根据广告的定向条件构建第一次索引
Conjunction id | ad list |
---|---|
1 | ad1 |
2 | ad2 |
3 | ad3 |
4 | ad4 |
第一层索引就是:ConjunctionId -> AdIds的映射,不同的广告可能有相同的id
然后构建第二层索引:
第二层索引就是:Assignment -> ConjunctionIds,不同的 ConjunctionId 可能包含相同的 Assignment;
检索
现在有一个用户请求广告,用户画像如下:
age ∈ {18-29} ^ region ∈ {SZ} ^ net∈ {WIFI} ^ app∈ {3301}
用的Conjunction size是3,大于3的就不需要考虑了 ,从小于等于3的开始。
size=3的,匹配满足的只有1,2/1,2/1 这三组,同时满足三个的就是只有1了;
同理size=2,只有3合适了,
比较到size=1时候,只有net∈ {WIFI} 符合,因为size=1 只要有一个条件符合就可以了,
但是有一个不属于的反向属性,这个属性出现在用户posList中,所以size=1的这一层没有符合条件的ConjunctionId
取并集获得符合要求的Conjunction id 只有1,3;
然后检索第一层索引:通过ConjunctionId 检索到对应的adId,然后取一个交集就可以获取到检索的符合条件的adList:{ad1,ad3}
参考:http://theory.stanford.edu/~sergei/papers/vldb09-indexing.pdf