[Spring cloud 광고 시스템 구현] 18. 광고 창의 검색
지난 절 에서 우 리 는 데이터 정보 에 따라 걸 러 내 는 코드 를 실 현 했 지만 우리 의 조건 은 여러 조건 으로 우리 에 게 전 달 된 검색 서비스 일 수 있다. 본 절 에서 우 리 는 홍보 단원 의 세 가지 차원 조건 에 따라 걸 러 내 는 것 을 계속 실현 했다.
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 getOrRelationUnitIds(Set adUnitIdsSet,
KeywordFeature keywordFeature,
HobbyFeatrue hobbyFeatrue,
DistrictFeature districtFeature) {
if (CollectionUtils.isEmpty(adUnitIdsSet)) return Collections.EMPTY_SET;
// , , ?
Set keywordUnitIdSet = new HashSet<>(adUnitIdsSet);
Set hobbyUnitIdSet = new HashSet<>(adUnitIdsSet);
Set 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 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 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 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 selectAdCreativeIds(List unitIndexObjects) {
if (CollectionUtils.isEmpty(unitIndexObjects)) return Collections.emptyList();
// ids
List result = new ArrayList<>();
for (AdUnitIndexObject unitIndexObject : unitIndexObjects) {
// id
Set 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 findAllByIds(Collection ids) {
if (CollectionUtils.isEmpty(ids)) return Collections.emptyList();
List result = new ArrayList<>();
for (Long id : ids) {
CreativeIndexObject object = get(id);
if (null != object)
result.add(object);
}
return result;
}
이로부터 우 리 는 원 하 는 홍보 유닛 과 홍보 아 이 디 어 를 얻 었 습 니 다. 홍보 유닛 은 홍보 계획 을 포함 하기 때문에 우리 가 원 하 는 데 이 터 는 모두 얻 을 수 있 습 니 다. 그 다음 에 우 리 는 현재 우리 가 조회 한 데이터 의 상 태 를 걸 러 야 합 니 다. 어떤 데 이 터 는 우리 가 논리 적 으로 삭 제 했 을 수도 있 습 니 다.따라서 얻 은 데이터 가 효과 가 있 는 지 판단 해 야 한다.
SearchImpl
류 에서 이 루어 집 니 다. /**
*
*/
private void filterAdUnitAndPlanStatus(List 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 unitIndexObjects = IndexDataTableUtils.of(AdUnitIndexAwareImpl.class).fetch(adUnitIdSet);
//
filterAdUnitAndPlanStatus(unitIndexObjects, CommonStatus.VALID);
// id list
List creativeIds = IndexDataTableUtils.of(CreativeRelationUnitIndexAwareImpl.class)
.selectAdCreativeIds(unitIndexObjects);
// ids
List creativeIndexObjects = IndexDataTableUtils.of(CreativeIndexAwareImpl.class)
...
광고 위치 adslot 에 따라 창의 데이터 에 대한 여과 실현
우리 의 광고 위 치 는 서로 다른 크기, 유형 이 있 기 때문에 우 리 는 우리 의 조회 차원 과 데이터 유형 에 부합 되 는 모든 조건 을 얻 은 후에 서로 다른 광고 위 치 를 대상 으로 서로 다른 광고 창의 정 보 를 보 여 줘 야 한다.
/**
*
*
* @param creativeIndexObjects
* @param width width
* @param height height
*/
private void filterCreativeByAdSlot(List creativeIndexObjects,
Integer width,
Integer height,
List 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 buildCreativeResponse(List creativeIndexObjects) {
if (CollectionUtils.isEmpty(creativeIndexObjects)) return Collections.EMPTY_LIST;
// , , ,
CreativeIndexObject randomObject = creativeIndexObjects.get(
Math.abs(new Random().nextInt()) % creativeIndexObjects.size()
);
//List 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 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> adSlotRelationAds = response.getAdSlotRelationAds();
for (AdSlot adSlot : adSlotList) {
Set targetUnitIdSet;
//
Set 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 unitIndexObjects = IndexDataTableUtils.of(AdUnitIndexAwareImpl.class)
.fetch(targetUnitIdSet);
//
filterAdUnitAndPlanStatus(unitIndexObjects, CommonStatus.VALID);
// id list
List creativeIds = IndexDataTableUtils.of(CreativeRelationUnitIndexAwareImpl.class)
.selectAdCreativeIds(unitIndexObjects);
// ids
List creativeIndexObjects = IndexDataTableUtils.of(CreativeIndexAwareImpl.class)
.fetch(creativeIds);
// adslot
filterCreativeByAdSlot(creativeIndexObjects, adSlot.getWidth(), adSlot.getHeight(), adSlot.getType());
// , ,
adSlotRelationAds.put(
adSlot.getAdSlotCode(),
buildCreativeResponse(creativeIndexObjects)
);
}
return response;
}
...
검색 서비스 대외 제공
SearchController
에서 제공 해 야 한다. @PostMapping("/fetchAd")
public SearchResponse fetchAdCreative(@RequestBody SearchRequest request) {
log.info("ad-serach: fetchAd ->{}", JSON.toJSONString(request));
return search.fetchAds(request);
}
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 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.