트래픽의 유형에 따라 17 쿼리 광고 [광고 시스템의 단계를 구현하여 봄 클라우드 단계]

광고 검색 서비스

특징

검색 기능

미디어 광장 (APP 전화 디스플레이 광고는 개방 도로에 걷는 등을 큰 화면 광고를 볼 수 있습니다)

요청 데이터 객체 구현

우리는, 우리가 미디어의 방향으로 개시 요청 검색 시스템 광고, 그림에서 볼 수있는 요청 매개 변수의 정보에 많은 요청을 할 수 있습니다, 그들은 세 부분으로 나누어, 우리는 객체 정보를 캡슐화 이러한 매개 변수를 인코딩 우리 정보 자체를 요청합니다. 의 코드를 보자.

  • 만들기 광고 검색 요청 인터페이스

/**
 * ISearch for 请求接口,
 * 根据广告请求对象,获取广告响应信息
 *
 * @author <a href="mailto:[email protected]">Isaac.Zhang | 若初</a>
 */
@FunctionalInterface
public interface ISearch {

    /**
     * 根据请求返回广告结果
     */
    SearchResponse fetchAds(SearchRequest request);
}
  • SearchRequest에 만들기, 세 부분으로 구성 mediaId, RequestInfo,FeatureInfo
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SearchRequest {

    //媒体方请求标示
    private String mediaId;
    //请求基本信息
    private RequestInfo requestInfo;
    //匹配信息
    private FeatureInfo featureInfo;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class RequestInfo {
        private String requestId;

        private List<AdSlot> adSlots;
        private App app;
        private Geo geo;
        private Device device;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class FeatureInfo {

        private KeywordFeature keywordFeature;
        private DistrictFeature districtFeature;
        private HobbyFeatrue hobbyFeatrue;

        private FeatureRelation relation = FeatureRelation.AND;
    }
}

다른 목적은 당신이 갈 수 GitHub의 포털gitee 포털 소스 코드를 다운로드 할 수 있습니다.

UTOOLS1565403569539.png

검색 응답 객체 정의
/**
 * SearchResponse for 检索API响应对象
 *
 * @author <a href="mailto:[email protected]">Isaac.Zhang | 若初</a>
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SearchResponse {

    //一个广告位,可以展示多个广告
    //Map key为广告位 AdSlot#adSlotCode
    public Map<String, List<Creative>> adSlotRelationAds = new HashMap<>();

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Creative {

        private Long adId;
        private String adUrl;
        private Integer width;
        private Integer height;
        private Integer type;
        private Integer materialType;

        //展示监控url
        private List<String> showMonitorUrl = Arrays.asList("www.life-runner.com", "www.babydy.cn");
        //点击监控url
        private List<String> clickMonitorUrl = Arrays.asList("www.life-runner.com", "www.babydy.cn");
    }

    /**
     * 我们的检索服务针对的是内存中的索引检索,那么我们就需要一个转换方法
     */
    public static Creative convert(CreativeIndexObject object) {

        return Creative.builder()
                       .adId(object.getAdId())
                       .adUrl(object.getAdUrl())
                       .width(object.getWidth())
                       .height(object.getHeight())
                       .type(object.getType())
                       .materialType(object.getMaterialType())
                       .build();
    }
}
트래픽의 유형에 따라 광고 필터링

자체가 일반화 단위의 범주에 속하는 트래픽의 유형은 여러 종류가 있습니다 贴片广告, 开屏广告미디어 측이 서로 다른 유형의 트래픽에 따라 다른 광고 요청을 시작합니다 미디어 측의 종류에 동기화 할 필요가 등, 우리는 정보 흐름의 클래스 타입을 정의 할 필요가 .

public class AdUnitConstants {
    public static class PositionType{
        //App启动时展示的、展示时间短暂的全屏化广告形式。
        private static final int KAIPING = 1;
        //电影开始之前的广告
        private static final int TIEPIAN = 2;
        //电影播放中途广告
        private static final int TIEPIAN_MIDDLE = 4;
        //暂停视频时候播放的广告
        private static final int TIEPIAN_PAUSE = 8;
        //视频播放完
        private static final int TIEPIAN_POST = 16;
    }
}

도면 중 상술 한 유형에서, 우리는 비트의 동작 성능을 개선하기 위해 사용되는 2의 배수를 볼 수있다.

에서 com.sxzhongf.ad.index.adunit.AdUnitIndexObject중간, 우리는 검사 방법의 유형을 추가 :

public static boolean isAdSlotType(int adSlotType, int positionType) {
        switch (adSlotType) {
            case AdUnitConstants.PositionType.KAIPING:
                return isKaiPing(positionType);
            case AdUnitConstants.PositionType.TIEPIAN:
                return isTiePian(positionType);
            case AdUnitConstants.PositionType.TIEPIAN_MIDDLE:
                return isTiePianMiddle(positionType);
            case AdUnitConstants.PositionType.TIEPIAN_PAUSE:
                return isTiePianPause(positionType);
            case AdUnitConstants.PositionType.TIEPIAN_POST:
                return isTiePianPost(positionType);
            default:
                return false;
        }
    }

    /**
     * 与运算,低位取等,高位补零。
     * 如果 > 0,则为开屏
     */
    private static boolean isKaiPing(int positionType) {
        return (positionType & AdUnitConstants.PositionType.KAIPING) > 0;
    }
    private static boolean isTiePianMiddle(int positionType) {
        return (positionType & AdUnitConstants.PositionType.TIEPIAN_MIDDLE) > 0;
    }

    private static boolean isTiePianPause(int positionType) {
        return (positionType & AdUnitConstants.PositionType.TIEPIAN_PAUSE) > 0;
    }

    private static boolean isTiePianPost(int positionType) {
        return (positionType & AdUnitConstants.PositionType.TIEPIAN_POST) > 0;
    }

    private static boolean isTiePian(int positionType) {
        return (positionType & AdUnitConstants.PositionType.TIEPIAN) > 0;
    }

어떻게 우리가 전에 우리 모두가, 데이터 쿼리 positionType에 따라 필터링 할 필요가, 아무것도하지 않고 com.sxzhongf.ad.index.adunit.AdUnitIndexAwareImpl필터링을 달성하기 위해 두 가지 방법을 추가 :

/**
     * 过滤当前是否存在满足positionType的UnitIds
     */
    public Set<Long> match(Integer positionType) {
        Set<Long> adUnitIds = new HashSet<>();
        objectMap.forEach((k, v) -> {
            if (AdUnitIndexObject.isAdSlotType(positionType, v.getPositionType())) {
                adUnitIds.add(k);
            }
        });
        return adUnitIds;
    }

    /**
     * 根据UnitIds查询AdUnit list
     */
    public List<AdUnitIndexObject> fetch(Collection<Long> adUnitIds) {
        if (CollectionUtils.isEmpty(adUnitIds)) {
            return Collections.EMPTY_LIST;
        }
        List<AdUnitIndexObject> result = new ArrayList<>();
        adUnitIds.forEach(id -> {
            AdUnitIndexObject object = get(id);
            if (null == object) {
                log.error("AdUnitIndexObject does not found:{}", id);
                return;
            }
            result.add(object);
        });

        return result;
    }
  • 검색 서비스 인터페이스를 구현

우리는 위의 쿼리 메소드의 일련의 준비, 우리는 우리의 쿼리 인터페이스, 쿼리 인터페이스, 우리는 요청 객체 정보 미디어 측에 얻을 수 있습니다, 그것은 일련의 쿼리와 함께 제공 달성하기 위해 시작 트래픽을 광고 단위의 유형에 따라 정보를 조회하는 것입니다 필요한 필터 매개 변수 :

/**
 * SearchImpl for 实现search 服务
 *
 * @author <a href="mailto:[email protected]">Isaac.Zhang | 若初</a>
 */
@Service
@Slf4j
public class SearchImpl implements ISearch {
    @Override
    public SearchResponse fetchAds(SearchRequest request) {

        //获取请求广告位信息
        List<AdSlot> adSlotList = request.getRequestInfo().getAdSlots();

        //获取三个Feature信息
        KeywordFeature keywordFeature = request.getFeatureInfo().getKeywordFeature();
        HobbyFeatrue hobbyFeatrue = request.getFeatureInfo().getHobbyFeatrue();
        DistrictFeature districtFeature = request.getFeatureInfo().getDistrictFeature();
        //Feature关系
        FeatureRelation featureRelation = request.getFeatureInfo().getRelation();

        //构造响应对象
        SearchResponse response = new SearchResponse();
        Map<String, List<SearchResponse.Creative>> adSlotRelationAds = response.getAdSlotRelationAds();

        for (AdSlot adSlot : adSlotList) {
            Set<Long> targetUnitIdSet;
            //根据流量类型从缓存中获取 初始 广告信息
            Set<Long> adUnitIdSet = IndexDataTableUtils.of(
                    AdUnitIndexAwareImpl.class
            ).match(adSlot.getPositionType());
        }
        return null;
    }
}

추천

출처blog.51cto.com/1917331/2428999