中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring cloud 查詢返回廣告創意實例代碼

發布時間:2020-10-17 20:59:29 來源:腳本之家 閱讀:128 作者:zhangpan0614 欄目:編程語言

根據三個維度繼續過濾

在上一節中我們實現了根據流量信息過濾的代碼,但是我們的條件有可能是多條件一起傳給我們的檢索服務的,本節我們繼續實現根據推廣單元的三個維度條件的過濾。

在SearchImpl類中添加過濾方法

public class SearchImpl implements ISearch {
  @Override
  public SearchResponse fetchAds(SearchRequest request) {
    ...
      // 根據三個維度過濾
      if (featureRelation == FeatureRelation.AND) {
        filterKeywordFeature(adUnitIdSet, keywordFeature);
        filterHobbyFeature(adUnitIdSet, hobbyFeatrue);
        filterDistrictFeature(adUnitIdSet, districtFeature);

        targetUnitIdSet = adUnitIdSet;
      } else {
        getOrRelationUnitIds(adUnitIdSet, keywordFeature, hobbyFeatrue, districtFeature);
      }
    }
    return null;
  }

定義三個方法實現過濾

/**
   * 獲取三個維度各自滿足時的廣告id
   */
  private Set<Long> getOrRelationUnitIds(Set<Long> adUnitIdsSet,
                      KeywordFeature keywordFeature,
                      HobbyFeatrue hobbyFeatrue,
                      DistrictFeature districtFeature) {
    if (CollectionUtils.isEmpty(adUnitIdsSet)) return Collections.EMPTY_SET;

    // 我們在處理的時候,需要對副本進行處理,大家可以考慮一下為什么需要這么做?
    Set<Long> keywordUnitIdSet = new HashSet<>(adUnitIdsSet);
    Set<Long> hobbyUnitIdSet = new HashSet<>(adUnitIdsSet);
    Set<Long> districtUnitIdSet = new HashSet<>(adUnitIdsSet);

    filterKeywordFeature(keywordUnitIdSet, keywordFeature);
    filterHobbyFeature(hobbyUnitIdSet, hobbyFeatrue);
    filterDistrictFeature(districtUnitIdSet, districtFeature);

    // 返回它們的并集
    return new HashSet<>(
        CollectionUtils.union(
            CollectionUtils.union(keywordUnitIdSet, hobbyUnitIdSet),
            districtUnitIdSet
        )
    );
  }

  /**
   * 根據傳遞的關鍵詞過濾
   */
  private void filterKeywordFeature(Collection<Long> adUnitIds, KeywordFeature keywordFeature) {
    if (CollectionUtils.isEmpty(adUnitIds)) return;
    if (CollectionUtils.isNotEmpty(keywordFeature.getKeywords())) {
      // 如果存在需要過濾的關鍵詞,查找索引實例對象進行過濾處理
      CollectionUtils.filter(
          adUnitIds,
          adUnitId -> IndexDataTableUtils.of(UnitKeywordIndexAwareImpl.class)
                          .match(adUnitId, keywordFeature.getKeywords())
      );
    }
  }

  /**
   * 根據傳遞的興趣信息過濾
   */
  private void filterHobbyFeature(Collection<Long> adUnitIds, HobbyFeatrue hobbyFeatrue) {
    if (CollectionUtils.isEmpty(adUnitIds)) return;
    // 如果存在需要過濾的興趣,查找索引實例對象進行過濾處理
    if (CollectionUtils.isNotEmpty(hobbyFeatrue.getHobbys())) {
      CollectionUtils.filter(
          adUnitIds,
          adUnitId -> IndexDataTableUtils.of(UnitHobbyIndexAwareImpl.class)
                          .match(adUnitId, hobbyFeatrue.getHobbys())
      );
    }
  }

  /**
   * 根據傳遞的地域信息過濾
   */
  private void filterDistrictFeature(Collection<Long> adUnitIds, DistrictFeature districtFeature) {
    if (CollectionUtils.isEmpty(adUnitIds)) return;
    // 如果存在需要過濾的地域信息,查找索引實例對象進行過濾處理
    if (CollectionUtils.isNotEmpty(districtFeature.getProvinceAndCities())) {
      CollectionUtils.filter(
          adUnitIds,
          adUnitId -> {
            return IndexDataTableUtils.of(UnitDistrictIndexAwareImpl.class)
                         .match(adUnitId, districtFeature.getProvinceAndCities());
          }
      );
    }
  }

根據推廣單元id獲取推廣創意

我們知道,推廣單元和推廣創意的關系是多對多,從上文我們查詢到了推廣單元ids,接下來我們實現根據推廣單元id獲取推廣創意的代碼,let's code.

首先,我們需要在com.sxzhongf.ad.index.creative_relation_unit.CreativeRelationUnitIndexAwareImpl 關聯索引中查到推廣創意的ids

/**
   * 通過推廣單元id獲取推廣創意id
   */
  public List<Long> selectAdCreativeIds(List<AdUnitIndexObject> unitIndexObjects) {
    if (CollectionUtils.isEmpty(unitIndexObjects)) return Collections.emptyList();

    //獲取要返回的廣告創意ids
    List<Long> result = new ArrayList<>();
    for (AdUnitIndexObject unitIndexObject : unitIndexObjects) {
      //根據推廣單元id獲取推廣創意
      Set<Long> adCreativeIds = unitRelationCreativeMap.get(unitIndexObject.getUnitId());
      if (CollectionUtils.isNotEmpty(adCreativeIds)) result.addAll(adCreativeIds);
    }

    return result;
  }

然后得到了推廣創意的id list后,我們在創意索引實現類com.sxzhongf.ad.index.creative.CreativeIndexAwareImpl中定義根據ids查詢創意的方法。

/**
 * 根據ids獲取創意list
 */
public List<CreativeIndexObject> findAllByIds(Collection<Long> ids) {
  if (CollectionUtils.isEmpty(ids)) return Collections.emptyList();
  List<CreativeIndexObject> result = new ArrayList<>();

  for (Long id : ids) {
    CreativeIndexObject object = get(id);
    if (null != object)
      result.add(object);
  }

  return result;
}

自此,我們已經得到了想要的推廣單元和推廣創意,因為推廣單元包含了推廣計劃,所以我們想要的數據已經全部可以獲取到了,接下來,我們還得過濾一次當前我們查詢到的數據的狀態,因為有的數據,我們可能已經進行過邏輯刪除了,因此還需要判斷獲取的數據是否有效。在SearchImpl類中實現。

 /**
  * 根據狀態信息過濾數據
  */
 private void filterAdUnitAndPlanStatus(List<AdUnitIndexObject> unitIndexObjects, CommonStatus status) {
   if (CollectionUtils.isEmpty(unitIndexObjects)) return;

   //同時判斷推廣單元和推廣計劃的狀態
   CollectionUtils.filter(
       unitIndexObjects,
       unitIndexObject -> unitIndexObject.getUnitStatus().equals(status.getStatus()) &&
           unitIndexObject.getAdPlanIndexObject().getPlanStatus().equals(status.getStatus())
   );
 }

在SearchImpl中我們實現廣告創意的查詢.

...

//獲取 推廣計劃 對象list
List<AdUnitIndexObject> unitIndexObjects = IndexDataTableUtils.of(AdUnitIndexAwareImpl.class).fetch(adUnitIdSet);
//根據狀態過濾數據
filterAdUnitAndPlanStatus(unitIndexObjects, CommonStatus.VALID);
//獲取 推廣創意 id list
List<Long> creativeIds = IndexDataTableUtils.of(CreativeRelationUnitIndexAwareImpl.class)
                      .selectAdCreativeIds(unitIndexObjects);
//根據 推廣創意ids獲取推廣創意
List<CreativeIndexObject> creativeIndexObjects = IndexDataTableUtils.of(CreativeIndexAwareImpl.class)
...

根據廣告位adslot 實現對創意數據的過濾

因為我們的廣告位是有不同的大小,不同的類型,因此,我們在獲取到所有符合我們查詢維度以及流量類型的條件后,還需要針對不同的廣告位來展示不同的廣告創意信息。

/**
* 根據廣告位類型以及參數獲取展示的合適廣告信息
*
* @param creativeIndexObjects 所有廣告創意
* @param width        廣告位width
* @param height        廣告位height
*/
private void filterCreativeByAdSlot(List<CreativeIndexObject> creativeIndexObjects,
                 Integer width,
                 Integer height,
                 List<Integer> type) {
 if (CollectionUtils.isEmpty(creativeIndexObjects)) return;

 CollectionUtils.filter(
     creativeIndexObjects,
     creative -> {
       //審核狀態必須是通過
       return creative.getAuditStatus().equals(CommonStatus.VALID.getStatus())
           && creative.getWidth().equals(width)
           && creative.getHeight().equals(height)
           && type.contains(creative.getType());
     }
 );
}

組建搜索返回對象

正常業務場景中,同一個廣告位可以展示多個廣告信息,也可以只展示一個廣告信息,這個需要根據具體的業務場景來做不同的處理,本次為了演示方便,會從返回的創意列表中隨機選擇一個創意廣告信息進行展示,當然大家也可以根據業務類型,設置不同的優先級或者權重值來進行廣告選擇。

/**
 * 從創意列表中隨機獲取一條創意廣告返回出去
 *
 * @param creativeIndexObjects 創意廣告list
 */
private List<SearchResponse.Creative> buildCreativeResponse(List<CreativeIndexObject> creativeIndexObjects) {
  if (CollectionUtils.isEmpty(creativeIndexObjects)) return Collections.EMPTY_LIST;

  //隨機獲取一個廣告創意,也可以實現優先級排序,也可以根據權重值等等,具體根據業務
  CreativeIndexObject randomObject = creativeIndexObjects.get(
      Math.abs(new Random().nextInt()) % creativeIndexObjects.size()
  );
  //List<SearchResponse.Creative> result = new ArrayList<>();
  //result.add(SearchResponse.convert(randomObject));

  return Collections.singletonList(
      SearchResponse.convert(randomObject)
  );
}

完整的請求過濾實現方法:

@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());

      // 根據三個維度過濾
      if (featureRelation == FeatureRelation.AND) {
        filterKeywordFeature(adUnitIdSet, keywordFeature);
        filterHobbyFeature(adUnitIdSet, hobbyFeatrue);
        filterDistrictFeature(adUnitIdSet, districtFeature);

        targetUnitIdSet = adUnitIdSet;
      } else {
        targetUnitIdSet = getOrRelationUnitIds(adUnitIdSet, keywordFeature, hobbyFeatrue, districtFeature);
      }
      //獲取 推廣計劃 對象list
      List<AdUnitIndexObject> unitIndexObjects = IndexDataTableUtils.of(AdUnitIndexAwareImpl.class)
                                     .fetch(targetUnitIdSet);
      //根據狀態過濾數據
      filterAdUnitAndPlanStatus(unitIndexObjects, CommonStatus.VALID);

      //獲取 推廣創意 id list
      List<Long> creativeIds = IndexDataTableUtils.of(CreativeRelationUnitIndexAwareImpl.class)
                            .selectAdCreativeIds(unitIndexObjects);
      //根據 推廣創意ids獲取推廣創意
      List<CreativeIndexObject> creativeIndexObjects = IndexDataTableUtils.of(CreativeIndexAwareImpl.class)
                                        .fetch(creativeIds);

      //根據 廣告位adslot 實現對創意數據的過濾
      filterCreativeByAdSlot(creativeIndexObjects, adSlot.getWidth(), adSlot.getHeight(), adSlot.getType());

      //一個廣告位可以展示多個廣告,也可以僅展示一個廣告,具體根據業務來定
      adSlotRelationAds.put(
          adSlot.getAdSlotCode(),
          buildCreativeResponse(creativeIndexObjects)
      );
    }

    return response;
  }
  ...

檢索服務對外提供

暴露API接口
上文中,我們實現了檢索服務的核心邏輯,接下來,我們需要對外暴露我們的廣告檢索服務接口,在SearchController中提供:

@PostMapping("/fetchAd")
  public SearchResponse fetchAdCreative(@RequestBody SearchRequest request) {
    log.info("ad-serach: fetchAd ->{}", JSON.toJSONString(request));
    return search.fetchAds(request);
  }

實現API網關配置

zuul:
routes:
  sponsor: #在路由中自定義服務路由名稱
  path: /ad-sponsor/**
  serviceId: mscx-ad-sponsor #微服務name
  strip-prefix: false
  search: #在路由中自定義服務路由名稱
  path: /ad-search/**
  serviceId: mscx-ad-search #微服務name
  strip-prefix: false
prefix: /gateway/api
strip-prefix: true #不對 prefix: /gateway/api 設置的路徑進行截取,默認轉發會截取掉配置的前綴

以上就是本次分享的全部知識點內容,感謝大家對億速云的支持

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

长治市| 曲阳县| 宁夏| 灌云县| 莱芜市| 云和县| 大余县| 辽源市| 玛多县| 中牟县| 新源县| 濉溪县| 蓬溪县| 黄骅市| 长岛县| 黄龙县| 邳州市| 沂南县| 浪卡子县| 四子王旗| 昭通市| 达拉特旗| 比如县| 门头沟区| 巫溪县| 河源市| 香格里拉县| 于都县| 饶河县| 青冈县| 兴海县| 聊城市| 海兴县| 铜梁县| 霞浦县| 河西区| 洪江市| 延庆县| 泌阳县| 汉阴县| 大石桥市|