Authored by hugufei

直通车-品类价格带和直通车-商品池开发

... ... @@ -7,7 +7,7 @@ import java.util.ArrayList;
import java.util.List;
/**
* 个性化因子参数
* 页面元素信息
*/
public class PagePersonalFactor implements Serializable {
... ... @@ -16,6 +16,7 @@ public class PagePersonalFactor implements Serializable {
private List<Integer> misortIds;
private List<Integer> brandIds;
private List<SortBrand> sortBrandList;
private List<Integer> addScorePoolIds;
public PagePersonalFactor() {
this.misortIds = new ArrayList<>();
... ... @@ -23,10 +24,11 @@ public class PagePersonalFactor implements Serializable {
this.sortBrandList = new ArrayList<>();
}
public PagePersonalFactor(List<Integer> misortIds, List<Integer> brandIds, List<SortBrand> sortBrandList) {
public PagePersonalFactor(List<Integer> misortIds, List<Integer> brandIds, List<SortBrand> sortBrandList, List<Integer> addScorePoolIds) {
this.misortIds = misortIds;
this.brandIds = brandIds;
this.sortBrandList = sortBrandList;
this.addScorePoolIds = addScorePoolIds;
}
public List<Integer> getMisortIds() {
... ... @@ -52,4 +54,12 @@ public class PagePersonalFactor implements Serializable {
public void setSortBrandList(List<SortBrand> sortBrandList) {
this.sortBrandList = sortBrandList;
}
public List<Integer> getAddScorePoolIds() {
return addScorePoolIds;
}
public void setAddScorePoolIds(List<Integer> addScorePoolIds) {
this.addScorePoolIds = addScorePoolIds;
}
}
... ...
... ... @@ -8,6 +8,9 @@ import com.yoho.search.common.SearchCommonService;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.core.personalized.models.SortBrand;
import com.yoho.search.models.aggregations.AggKeyCount;
import com.yoho.search.models.aggregations.AggKeyCountTwoLevel;
import com.yoho.search.service.helper.AggCommonHelper;
import com.yoho.search.service.helper.SearchParamHelper;
import com.yoho.search.service.recall.helper.ExtendFilterHelper;
import com.yoho.search.models.recall.ParamQueryFilter;
... ... @@ -78,12 +81,12 @@ public class QueryPageFactorBaseService extends AbstractCacheComponent<PagePerso
filter.must(old.getFiter());
filter.mustNot(ExtendFilterHelper.notRecallFilter());//聚合的时候带上不召回的数据
searchParam.setFiter(filter);
searchParam.setSize(0);
//2、构造聚合参数
List<AbstractAggregationBuilder<?>> aggregationBuilders = new ArrayList<>();
aggregationBuilders.add(brandSortAggBuilder());//品类-品牌聚合
aggregationBuilders.add(addScorePoolIdsBuilder());//商品池聚合
searchParam.setAggregationBuilders(aggregationBuilders);
//3、执行查询
... ... @@ -91,10 +94,15 @@ public class QueryPageFactorBaseService extends AbstractCacheComponent<PagePerso
//4、构造结果
Map<String, Aggregation> aggregationMap = searchResult.getAggMaps();
List<Integer> addScorePoolIds = this.genAddScorePoolIds(aggregationMap);
List<SortBrand> sortBrands = this.getBrandSortsFromAggregationMap(aggregationMap);
List<Integer> misortIds = this.getMisortIds(sortBrands);
List<Integer> brandIds = this.getBrandIds(sortBrands);
return new PagePersonalFactor(misortIds, brandIds, sortBrands);
return new PagePersonalFactor(misortIds, brandIds, sortBrands,addScorePoolIds);
}
private List<Integer> genAddScorePoolIds(Map<String, Aggregation> aggregationMap) {
return AggCommonHelper.getIdsFromAggMaps(aggregationMap,"addScorePoolIdsAgg");
}
private List<Integer> getMisortIds(List<SortBrand> sortBrands) {
... ... @@ -136,59 +144,80 @@ public class QueryPageFactorBaseService extends AbstractCacheComponent<PagePerso
return middleSortAggBuilder;
}
private List<SortBrand> getBrandSortsFromAggregationMap(Map<String, Aggregation> aggregationMap) {
Map<Integer, List<Integer>> brand2MiSortIdsMap = this.getValueFromAggregationMap(aggregationMap, "sortBrandBrandIdAgg", "sortBrandMiddleSortAgg");
List<SortBrand> pageBrandSorts = new ArrayList<>();
for (Map.Entry<Integer, List<Integer>> entry : brand2MiSortIdsMap.entrySet()) {
Integer brandId = entry.getKey();
List<Integer> misorts = entry.getValue();
for (Integer misort : misorts) {
pageBrandSorts.add(new SortBrand(misort, brandId));
}
}
return pageBrandSorts;
}
/**
* 从聚合结果中获取参数,仅支持二层聚合
* skn-商品池
*
* @param aggregationMap
* @param firstAggName
* @param secondAggName
* @return
*/
private Map<Integer, List<Integer>> getValueFromAggregationMap(Map<String, Aggregation> aggregationMap, String firstAggName, String secondAggName) {
Map<Integer, List<Integer>> aggResultMap = new HashMap<>();
if (!aggregationMap.containsKey(firstAggName)) {
return aggResultMap;
}
MultiBucketsAggregation firstAggregation = (MultiBucketsAggregation) aggregationMap.get(firstAggName);
Iterator<? extends MultiBucketsAggregation.Bucket> firstAggregationIterator = firstAggregation.getBuckets().iterator();
while (firstAggregationIterator.hasNext()) {
MultiBucketsAggregation.Bucket firstAggregationBucket = firstAggregationIterator.next();
Integer firstAggregationBucketKey = Integer.valueOf(firstAggregationBucket.getKeyAsString());
Map<String, Aggregation> secondAggregationMap = firstAggregationBucket.getAggregations().asMap();
if (secondAggregationMap == null || !secondAggregationMap.containsKey(secondAggName)) {
continue;
}
List<Integer> secondAggregationBucketKeys = this.getAggValuesFromMultiBucketsAggregation((MultiBucketsAggregation) secondAggregationMap.get(secondAggName));
aggResultMap.put(firstAggregationBucketKey, secondAggregationBucketKeys);
}
return aggResultMap;
private TermsAggregationBuilder addScorePoolIdsBuilder() {
TermsAggregationBuilder addScorePoolIdsAggBuilder = AggregationBuilders.terms("addScorePoolIdsAgg").field(ProductIndexEsField.toAddScorePoolIds).size(20);
return addScorePoolIdsAggBuilder;
}
private List<Integer> getAggValuesFromMultiBucketsAggregation(MultiBucketsAggregation aggregation) {
List<Integer> results = new ArrayList<>();
if (aggregation == null) {
return results;
}
Iterator<? extends MultiBucketsAggregation.Bucket> bucketsIterator = aggregation.getBuckets().iterator();
while (bucketsIterator.hasNext()) {
MultiBucketsAggregation.Bucket bucket = bucketsIterator.next();
Integer value = Integer.valueOf(bucket.getKeyAsString());
results.add(value);
private List<SortBrand> getBrandSortsFromAggregationMap(Map<String, Aggregation> aggregationMap) {
List<AggKeyCountTwoLevel> results = AggCommonHelper.getAggKeyCountTwoLevelList(aggregationMap,"sortBrandBrandIdAgg","sortBrandMiddleSortAgg");
List<SortBrand> pageBrandSorts = new ArrayList<>();
for (AggKeyCountTwoLevel aggKeyCountTwoLevel : results) {
Integer brandId = aggKeyCountTwoLevel.getFirstAggKeyCount().getKey();
List<AggKeyCount> misortInfos = aggKeyCountTwoLevel.getSecondAggKeyCountList();
for (AggKeyCount misortInfo : misortInfos) {
pageBrandSorts.add(new SortBrand(misortInfo.getKey(), brandId));
}
return results;
}
return pageBrandSorts;
// Map<Integer, List<Integer>> brand2MiSortIdsMap = this.getValueFromAggregationMap(aggregationMap, "sortBrandBrandIdAgg", "sortBrandMiddleSortAgg");
// List<SortBrand> pageBrandSorts = new ArrayList<>();
// for (Map.Entry<Integer, List<Integer>> entry : brand2MiSortIdsMap.entrySet()) {
// Integer brandId = entry.getKey();
// List<Integer> misorts = entry.getValue();
// for (Integer misort : misorts) {
// pageBrandSorts.add(new SortBrand(misort, brandId));
// }
// }
// return pageBrandSorts;
}
// /**
// * 从聚合结果中获取参数,仅支持二层聚合
// *
// * @param aggregationMap
// * @param firstAggName
// * @param secondAggName
// * @return
// */
// private Map<Integer, List<Integer>> getValueFromAggregationMap(Map<String, Aggregation> aggregationMap, String firstAggName, String secondAggName) {
// Map<Integer, List<Integer>> aggResultMap = new HashMap<>();
// if (!aggregationMap.containsKey(firstAggName)) {
// return aggResultMap;
// }
// MultiBucketsAggregation firstAggregation = (MultiBucketsAggregation) aggregationMap.get(firstAggName);
// Iterator<? extends MultiBucketsAggregation.Bucket> firstAggregationIterator = firstAggregation.getBuckets().iterator();
// while (firstAggregationIterator.hasNext()) {
// MultiBucketsAggregation.Bucket firstAggregationBucket = firstAggregationIterator.next();
// Integer firstAggregationBucketKey = Integer.valueOf(firstAggregationBucket.getKeyAsString());
// Map<String, Aggregation> secondAggregationMap = firstAggregationBucket.getAggregations().asMap();
// if (secondAggregationMap == null || !secondAggregationMap.containsKey(secondAggName)) {
// continue;
// }
// List<Integer> secondAggregationBucketKeys = this.getAggValuesFromMultiBucketsAggregation((MultiBucketsAggregation) secondAggregationMap.get(secondAggName));
// aggResultMap.put(firstAggregationBucketKey, secondAggregationBucketKeys);
// }
// return aggResultMap;
// }
//
// private List<Integer> getAggValuesFromMultiBucketsAggregation(MultiBucketsAggregation aggregation) {
// List<Integer> results = new ArrayList<>();
// if (aggregation == null) {
// return results;
// }
// Iterator<? extends MultiBucketsAggregation.Bucket> bucketsIterator = aggregation.getBuckets().iterator();
// while (bucketsIterator.hasNext()) {
// MultiBucketsAggregation.Bucket bucket = bucketsIterator.next();
// Integer value = Integer.valueOf(bucket.getKeyAsString());
// results.add(value);
// }
// return results;
// }
}
... ...
... ... @@ -3,17 +3,20 @@ package com.yoho.search.service.recall.beans;
import com.alibaba.fastjson.JSON;
import com.yoho.search.core.personalized.models.SortBrand;
import com.yoho.search.dal.model.CsRecallConfigSortPrice;
import com.yoho.search.models.recall.SortBrandSknCount;
import com.yoho.search.models.recall.PagePersonalFactor;
import com.yoho.search.models.recall.SortBrandSknCount;
import com.yoho.search.models.recall.UserRecallRequest;
import com.yoho.search.service.recall.reloadable.*;
import com.yoho.search.service.recall.strategy.SortBrandType;
import com.yoho.search.service.recall.strategy.StrategyEnum;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
... ... @@ -143,4 +146,27 @@ public class RecallConfigService {
return configSortPriceService.randomConfigSortPrice(pageFactor, count);
}
/**
* 随机获取商品池
*
* @param pageFactor
* @param count
* @return
*/
public List<Integer> randomDirectTrainSknPoolIds(PagePersonalFactor pageFactor, int count) {
if (count <= 0 || CollectionUtils.isEmpty(pageFactor.getAddScorePoolIds())){
return new ArrayList<>();
}
List<Integer> copyList = new ArrayList<>(pageFactor.getAddScorePoolIds());
Collections.shuffle(copyList);
List<Integer> results = new ArrayList<>();
for (Integer sknPoolIds : copyList) {
if (results.size() >= count) {
break;
}
results.add(sknPoolIds);
}
return results;
}
}
... ...
... ... @@ -23,6 +23,8 @@ public class CommonRecallRequestBuilder {
@Autowired
private DirectTrainBrandRequestsBuiler directTrainBrandRequestsBuiler;
@Autowired
private DirectTrainSknPoolRequestsBuilder directTrainSknPoolRequestsBuilder;
@Autowired
private DirectTrainSortPriceRequestsBuilder directTrainSortPriceRequestsBuilder;
/**
... ... @@ -49,10 +51,11 @@ public class CommonRecallRequestBuilder {
requests.addAll(this.buildUfoDirectTrainRequest(userRecallRequest));
//6.3) 直通车-品牌召回
requests.addAll(directTrainBrandRequestsBuiler.buildDirectTrainBrandRequests(userRecallRequest, pagePersonalFactor));
//6.4) 直通车-品类价格带
//6.4) 直通车-商品池
requests.addAll(directTrainSknPoolRequestsBuilder.buildDirectTrainSknPoolRequests(userRecallRequest, pagePersonalFactor));
//6.5) 直通车-品类价格带
requests.addAll(directTrainSortPriceRequestsBuilder.buildDirectTrainSortPriceRequests(userRecallRequest, pagePersonalFactor));
//7、 随机召回
requests.addAll(this.buildCommonRandomStrategy(userRecallRequest));
//8、 页面的兜底召回
... ...
package com.yoho.search.service.recall.beans.requests;
import com.alibaba.fastjson.JSON;
import com.yoho.search.models.recall.PagePersonalFactor;
import com.yoho.search.models.recall.RecallRequest;
import com.yoho.search.models.recall.UserRecallRequest;
import com.yoho.search.service.recall.beans.RecallConfigService;
import com.yoho.search.service.recall.helper.RecallConfigConstants;
import com.yoho.search.service.recall.strategy.IStrategy;
import com.yoho.search.service.recall.strategy.StrategyEnum;
import com.yoho.search.service.recall.strategy.impls.DirectTrainSknPoolStrategy;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Component
public class DirectTrainSknPoolRequestsBuilder {
private static final Logger RECALL_NEW_LOGGER = LoggerFactory.getLogger("RECALL");
@Autowired
private RecallConfigService recallConfigService;
/**
* 构造直通车-[品类价格带]的召回请求
*
* @param userRecallRequest
* @return
*/
public List<RecallRequest> buildDirectTrainSknPoolRequests(UserRecallRequest userRecallRequest, PagePersonalFactor pageFactor) {
int size = recallConfigService.queryStrategyConfigSize(userRecallRequest, StrategyEnum.DIRECT_TRAIN_SKN_POOL, 0);
if (size == 0) {
return Collections.emptyList();
}
List<Integer> randomDirectTrainSknPoolIdList = recallConfigService.randomDirectTrainSknPoolIds(pageFactor, size);
if (CollectionUtils.isEmpty(randomDirectTrainSknPoolIdList)) {
return Collections.emptyList();
}
RECALL_NEW_LOGGER.info("directTrainSknPoolRequests is[{}]", JSON.toJSONString(randomDirectTrainSknPoolIdList));
List<RecallRequest> requests = new ArrayList<>();
int productSize = RecallConfigConstants.DEFAULT_DIRECT_TRAIN_PRODUCT_SIZE;
for (Integer sknPoolId : randomDirectTrainSknPoolIdList) {
IStrategy strategy = new DirectTrainSknPoolStrategy(sknPoolId, productSize);
requests.add(new RecallRequest(userRecallRequest.getParamQueryFilter(), strategy));
}
return requests;
}
}
... ...
... ... @@ -34,6 +34,7 @@ public class DirectTrainSortPriceRequestsBuilder {
* @param userRecallRequest
* @return
*/
public List<RecallRequest> buildDirectTrainSortPriceRequests(UserRecallRequest userRecallRequest, PagePersonalFactor pageFactor) {
int size = recallConfigService.queryStrategyConfigSize(userRecallRequest, StrategyEnum.DIRECT_TRAIN_SORT_PRICE, 0);
if (size == 0) {
... ...
... ... @@ -15,13 +15,13 @@ import org.elasticsearch.search.sort.SortBuilder;
public class DirectTrainSknPoolStrategy implements IStrategy {
private Integer poolId;
private int size;
public DirectTrainSknPoolStrategy(Integer poolId, int size){
this.poolId = poolId;
this.size = size;
}
private int size;
@Override
public StrategyEnum strategtEnum() {
return StrategyEnum.DIRECT_TRAIN_SKN_POOL;
... ...