1.完善UnitDistrict
public boolean match(Long adUnitId,
List<DistrictFeature.ProvinceAndCity> districts) {
if (unitDistrictMap.containsKey(adUnitId) &&
CollectionUtils.isNotEmpty(unitDistrictMap.get(adUnitId))) {
Set<String> unitDistricts = unitDistrictMap.get(adUnitId);
List<String> targetDistricts = districts.stream()
.map(
d -> CommonUtils.stringConcat(
d.getProvince(), d.getCity()
)
).collect(Collectors.toList());
return CollectionUtils.isSubCollection(targetDistricts, unitDistricts);
}
return false;
}
2.在 SearchImpl 中实现三重过滤:
由于限制间存在 AND 或者 OR 的关系,所以需要分情况进行过滤
@Slf4j
@Service
public class SearchImpl implements ISearch {
@Override
public SearchResponse fetchAds(SearchRequest request) {
// 请求的广告位信息
List<AdSlot> adSlots = request.getRequestInfo().getAdSlots();
// 三个 Feature
KeywordFeature keywordFeature = request.getFeatureInfo().getKeywordFeature();
DistrictFeature districtFeature = request.getFeatureInfo().getDistrictFeature();
ItFeature itFeature = request.getFeatureInfo().getItFeature();
FeatureRelation relation = request.getFeatureInfo().getRelation();
// 构造响应对象
SearchResponse response = new SearchResponse();
Map<String, List<SearchResponse.Creative>> adSlot2Ads = response.getAdSlot2Ads();
for (AdSlot adSlot : adSlots) {
Set<Long> targetUnitIdSet;
// 根据流量类型获取初始 AdUnit
Set<Long> adUnitIdSet = DataTable.of(
AdUnitIndex.class
).match(adSlot.getPositionType());
if (relation == FeatureRelation.AND){
//进行三重过滤
filterKeywordFeature(adUnitIdSet, keywordFeature);
filterDistrictFeature(adUnitIdSet, districtFeature);
filterItTagFeature(adUnitIdSet, itFeature);
targetUnitIdSet = adUnitIdSet;
}else {
targetUnitIdSet = getORRelationUnitIds(adUnitIdSet,keywordFeature,districtFeature,itFeature);
}
}
return null;
}
private Set<Long> getORRelationUnitIds(Set<Long> adUnitIdSet, KeywordFeature keywordFeature, DistrictFeature districtFeature, ItFeature itFeature) {
if (CollectionUtils.isEmpty(adUnitIdSet)) {
return Collections.emptySet();
}
Set<Long> keywordUnitIdSet = new HashSet<>(adUnitIdSet);
Set<Long> districtUnitIdSet = new HashSet<>(adUnitIdSet);
Set<Long> itUnitIdSet = new HashSet<>(adUnitIdSet);
filterKeywordFeature(keywordUnitIdSet, keywordFeature);
filterDistrictFeature(districtUnitIdSet, districtFeature);
filterItTagFeature(itUnitIdSet, itFeature);
return new HashSet<>(
CollectionUtils.union(CollectionUtils.union(keywordUnitIdSet, districtUnitIdSet), itUnitIdSet)
);
}
private void filterKeywordFeature(Collection<Long> adUnitIds, KeywordFeature keywordFeature) {
if (CollectionUtils.isEmpty(adUnitIds)) {
return;
}
if (CollectionUtils.isNotEmpty(keywordFeature.getKeywords())) {
CollectionUtils.filter(
adUnitIds,
adUnitId -> DataTable.of(UnitKeywordIndex.class).match(adUnitId, keywordFeature.getKeywords())
);
}
}
private void filterDistrictFeature(Collection<Long> adUnitIds, DistrictFeature districtFeature) {
if (CollectionUtils.isEmpty(adUnitIds)) {
return;
}
if (CollectionUtils.isNotEmpty(districtFeature.getDistricts())) {
CollectionUtils.filter(
adUnitIds,
adUnitId -> DataTable.of(UnitDistrictIndex.class).match(adUnitId, districtFeature.getDistricts())
);
}
}
private void filterItTagFeature(Collection<Long> adUnitIds, ItFeature itFeature) {
if (CollectionUtils.isEmpty(adUnitIds)) {
return;
}
if (CollectionUtils.isNotEmpty(itFeature.getIts())) {
CollectionUtils.filter(
adUnitIds,
adUnitId -> DataTable.of(UnitItIndex.class).match(adUnitId, itFeature.getIts())
);
}
}
}