Authored by zhaojun2

brand product

  1 +package com.yoho.search.service.scene.activity;
  2 +
  3 +import com.yoho.search.base.helper.Word2VectorCalculator;
  4 +import com.yoho.search.base.utils.CollectionUtils;
  5 +import com.yoho.search.cache.beans.AbstractCacheBean;
  6 +import com.yoho.search.core.personalized.models.UserPersonalFactorRspNew;
  7 +import com.yoho.search.service.recall.beans.persional.UserPersionalFactorComponent;
  8 +import com.yoho.search.service.recall.beans.strategy.IStrategy;
  9 +import com.yoho.search.service.recall.beans.strategy.impls.SortBrandHeatValueStrategy;
  10 +import com.yoho.search.service.recall.beans.vector.BrandVectorCacheBean;
  11 +import com.yoho.search.service.recall.models.common.ParamQueryFilter;
  12 +import com.yoho.search.service.recall.models.personal.BrandVectorScore;
  13 +import com.yoho.search.service.recall.models.personal.UserPersonalFactor;
  14 +import com.yoho.search.service.recall.models.req.RecallRequest;
  15 +import com.yoho.search.service.recall.models.req.RecallRequestResponse;
  16 +import com.yoho.search.service.recall.models.req.UserRecallRequest;
  17 +import org.springframework.beans.factory.annotation.Autowired;
  18 +import org.springframework.stereotype.Component;
  19 +
  20 +import java.util.*;
  21 +import java.util.stream.Collectors;
  22 +
  23 +@Component
  24 +public class AggBrandProductCacheBean extends AbstractCacheBean<BrandProductRequest, BrandProductResponse, BrandProductRequestResponse> {
  25 +
  26 + @Autowired
  27 + private AggBrandService aggBrandService;
  28 + @Autowired
  29 + private UserPersionalFactorComponent userComponent;
  30 + @Autowired
  31 + private BrandVectorCacheBean brandVectorCacheBean;
  32 + @Autowired
  33 + private BatchBrandProductCacheBean batchBrandProductCacheBean;
  34 +
  35 + /**
  36 + * 入口
  37 + * @return
  38 + */
  39 + public BrandProductResponse queryBrandProductResult(BrandProductRequest brandProductRequest) {
  40 + BrandProductRequestResponse brandProductRequestResponse = new BrandProductRequestResponse(brandProductRequest);
  41 + bacthFillResponseWithCache(brandProductRequestResponse, false);
  42 + return brandProductRequestResponse.getResponse();
  43 + }
  44 +
  45 + @Override
  46 + protected boolean useEhCache() {
  47 + return false;
  48 + }
  49 +
  50 + @Override
  51 + protected Map<BrandProductRequest, BrandProductResponse> queryMissCacheRequestResults(List<BrandProductRequestResponse> missCacheRequests) {
  52 + Map<BrandProductRequest, BrandProductResponse> results = new HashMap<>();
  53 + for (BrandProductRequestResponse request : missCacheRequests) {
  54 + BrandProductResponse response = doRealRecall(request.getRequest());
  55 + results.put(request.getRequest(), response);
  56 + }
  57 + return results;
  58 + }
  59 +
  60 + /**
  61 + * 真正的召回入口
  62 + *
  63 + * @param brandProductRequest
  64 + * @return
  65 + */
  66 + private BrandProductResponse doRealRecall(BrandProductRequest brandProductRequest) {
  67 + //1 获取个性化的和非个性化的brandId viewNum个
  68 + List<AggBrand> aggBrands = aggBrandService.aggBrands(brandProductRequest.getParamQueryFilter());
  69 + if (org.springframework.util.CollectionUtils.isEmpty(aggBrands)) {
  70 + return null;
  71 + }
  72 + List<Integer> aggBrandIds = aggBrands.stream().map(AggBrand::getBrandId).collect(Collectors.toList());
  73 + List<Integer> userPersonalbrandIds = new ArrayList<>();
  74 + if (brandProductRequest.hasUidOrUdid()) {
  75 + UserPersonalFactorRspNew userFactor = userComponent.queryUserPersionalFactor(brandProductRequest.getUid(), brandProductRequest.getUdid(), null);
  76 + userPersonalbrandIds = buildUserPersonalBrandIds(aggBrandIds, userFactor, brandProductRequest.getBrandCount());
  77 + }
  78 + if (userPersonalbrandIds.size() < brandProductRequest.getBrandCount()) {
  79 + aggBrandIds.removeAll(userPersonalbrandIds);
  80 + aggBrandIds = CollectionUtils.safeSubList(aggBrandIds, 0, brandProductRequest.getBrandCount() - userPersonalbrandIds.size());
  81 + }
  82 +
  83 + //2、获取召回结果
  84 + batchRecall(brandProductRequest, userPersonalbrandIds, aggBrandIds);
  85 +
  86 +
  87 +
  88 + return null;
  89 + }
  90 +
  91 + private List<Integer> buildUserPersonalBrandIds(List<Integer> aggBrandIds, UserPersonalFactorRspNew userFactor, int count) {
  92 + List<Integer> result = new ArrayList<>();
  93 + double userBrandVectorNorm = Word2VectorCalculator.getVectorListNorm(userFactor.getBrandVectorW2v());
  94 + List<BrandVectorScore> brandVectorScores = new ArrayList<>();
  95 +
  96 + for (Integer brandId : aggBrandIds) {
  97 + List<Double> brandVector = brandVectorCacheBean.queryBrandVector(brandId, false);
  98 + if (brandVector == null || brandVector.isEmpty()) {
  99 + continue;
  100 + }
  101 + double score = Word2VectorCalculator.calScore(userFactor.getBrandVectorW2v(), userBrandVectorNorm, brandVector);
  102 + brandVectorScores.add(new BrandVectorScore(brandId, score));
  103 + }
  104 + if (brandVectorScores != null && !brandVectorScores.isEmpty()){
  105 + Collections.sort(brandVectorScores, (o1, o2) -> o2.getScore().compareTo(o1.getScore()));//得分高的排在前面
  106 + brandVectorScores = CollectionUtils.safeSubList(brandVectorScores, 0, count);
  107 + for (BrandVectorScore brandVectorScore : brandVectorScores) {
  108 + result.add(brandVectorScore.getBrandId());
  109 + }
  110 + }
  111 + return result;
  112 + }
  113 +
  114 + private List<BrandProductRequestResponse> batchRecall(BrandProductRequest brandProductRequest, List<Integer> userPersonalbrandIds, List<Integer> aggBrandIds) {
  115 +
  116 + List<Integer> brandIds = new ArrayList<>(userPersonalbrandIds);
  117 + brandIds.addAll(aggBrandIds);
  118 + int brandProductCount = brandProductRequest.getBrandProductCount() + 10;
  119 + ParamQueryFilter paramQueryFilter = brandProductRequest.getParamQueryFilter();
  120 +
  121 + List<RecallRequest> brandRequests = brandIds.stream().map(brandId -> {
  122 + IStrategy strategy = new BrandHeatValueStrategy(brandId, brandProductCount);
  123 + return new RecallRequest(paramQueryFilter, strategy);
  124 + }).collect(Collectors.toList());
  125 +
  126 +
  127 +
  128 +
  129 +
  130 + return null;
  131 +
  132 + }
  133 +
  134 +}
  135 +
  136 +
  137 +
  138 +
  139 +
  140 +
  141 +
  142 +
  143 +
  144 +
  145 +
  146 +
  147 +
  148 +
  149 +
  150 +
  151 +
  152 +
  153 +
  154 +
  155 +
  156 +
  157 +
1 package com.yoho.search.service.scene.activity; 1 package com.yoho.search.service.scene.activity;
2 2
3 -import com.yoho.search.common.SearchCommonService;  
4 import com.yoho.search.models.SearchApiResult; 3 import com.yoho.search.models.SearchApiResult;
5 import com.yoho.search.service.helper.*; 4 import com.yoho.search.service.helper.*;
6 -import com.yoho.search.service.recall.beans.builder.UserRecallRequestBuilder;  
7 -import com.yoho.search.service.recall.beans.persional.UserPersionalFactorComponent;  
8 -import com.yoho.search.service.recall.beans.vector.BrandVectorCacheBean;  
9 import com.yoho.search.service.recall.models.common.ParamQueryFilter; 5 import com.yoho.search.service.recall.models.common.ParamQueryFilter;
10 import org.apache.commons.collections.MapUtils; 6 import org.apache.commons.collections.MapUtils;
11 import org.apache.commons.lang.StringUtils; 7 import org.apache.commons.lang.StringUtils;
@@ -28,7 +24,7 @@ public class AggBrandProductListService implements ApplicationEventPublisherAwar @@ -28,7 +24,7 @@ public class AggBrandProductListService implements ApplicationEventPublisherAwar
28 24
29 private ApplicationEventPublisher publisher; 25 private ApplicationEventPublisher publisher;
30 @Autowired 26 @Autowired
31 - private BrandProductCacheBean brandProductCacheBean; 27 + private AggBrandProductCacheBean brandProductCacheBean;
32 @Autowired 28 @Autowired
33 private SearchQueryHelper searchServiceHelepr; 29 private SearchQueryHelper searchServiceHelepr;
34 30
@@ -14,6 +14,7 @@ import com.yoho.search.cache.model.CacheObject; @@ -14,6 +14,7 @@ import com.yoho.search.cache.model.CacheObject;
14 import com.yoho.search.common.SearchCommonService; 14 import com.yoho.search.common.SearchCommonService;
15 import com.yoho.search.core.es.model.SearchParam; 15 import com.yoho.search.core.es.model.SearchParam;
16 import com.yoho.search.core.es.model.SearchResult; 16 import com.yoho.search.core.es.model.SearchResult;
  17 +import com.yoho.search.service.helper.SearchParamHelper;
17 import com.yoho.search.service.recall.models.common.ParamQueryFilter; 18 import com.yoho.search.service.recall.models.common.ParamQueryFilter;
18 import org.elasticsearch.index.query.BoolQueryBuilder; 19 import org.elasticsearch.index.query.BoolQueryBuilder;
19 import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; 20 import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
@@ -36,15 +37,14 @@ public class AggBrandService extends AbstractPageComponent<List<AggBrand>> { @@ -36,15 +37,14 @@ public class AggBrandService extends AbstractPageComponent<List<AggBrand>> {
36 37
37 @Autowired 38 @Autowired
38 private SearchCommonService searchCommonService; 39 private SearchCommonService searchCommonService;
  40 + @Autowired
  41 + private SearchParamHelper searchParamHelper;
39 42
40 public List<AggBrand> aggBrands(ParamQueryFilter paramQueryFilter) { 43 public List<AggBrand> aggBrands(ParamQueryFilter paramQueryFilter) {
41 RedisKeyBuilder redisKeyBuilder = this.genRedisKeyBuilder(paramQueryFilter); 44 RedisKeyBuilder redisKeyBuilder = this.genRedisKeyBuilder(paramQueryFilter);
42 List<AggBrand> value = queryFromCache(redisKeyBuilder); 45 List<AggBrand> value = queryFromCache(redisKeyBuilder);
43 if (CollectionUtils.isEmpty(value)) { 46 if (CollectionUtils.isEmpty(value)) {
44 -  
45 -  
46 -  
47 -// value = getFromEs(searchParam); 47 + value = getFromEs(searchParamHelper.buildSearchParam(paramQueryFilter));
48 if (!CollectionUtils.isEmpty(value)) { 48 if (!CollectionUtils.isEmpty(value)) {
49 addToRedisAndEhcache(redisKeyBuilder, value); 49 addToRedisAndEhcache(redisKeyBuilder, value);
50 } 50 }
  1 +package com.yoho.search.service.scene.activity;
  2 +
  3 +
  4 +import com.yoho.search.base.utils.ISearchConstants;
  5 +import com.yoho.search.base.utils.ProductIndexEsField;
  6 +import com.yoho.search.cache.beans.AbstractCacheBean;
  7 +import com.yoho.search.common.SearchCommonService;
  8 +import com.yoho.search.core.es.model.SearchParam;
  9 +import com.yoho.search.core.es.model.SearchResult;
  10 +import com.yoho.search.service.recall.models.req.RecallRequest;
  11 +import com.yoho.search.service.recall.models.req.RecallRequestResponse;
  12 +import com.yoho.search.service.recall.models.req.RecallResponse;
  13 +import com.yoho.search.service.recall.models.req.SknBaseInfoResponse;
  14 +import org.apache.commons.collections.MapUtils;
  15 +import org.springframework.beans.factory.annotation.Autowired;
  16 +import org.springframework.stereotype.Component;
  17 +
  18 +import java.util.*;
  19 +
  20 +@Component
  21 +public class BatchBrandProductCacheBean extends AbstractCacheBean<RecallRequest, SknBaseInfoResponse, BatchBrandProductRequestResponse> {
  22 +
  23 +
  24 + @Autowired
  25 + private SearchCommonService searchCommonService;
  26 +
  27 + /**
  28 + * 批量召回入口
  29 + *
  30 + * @param batchRecallRequests
  31 + * @return
  32 + */
  33 + public List<BatchBrandProductRequestResponse> batchRecallAndCache(final List<RecallRequest> batchRecallRequests) {
  34 + //1、构造请求
  35 + final List<BatchBrandProductRequestResponse> results = new ArrayList<>();
  36 + for (RecallRequest request : batchRecallRequests) {
  37 + results.add(new BatchBrandProductRequestResponse(request));
  38 + }
  39 + //2、执行查询
  40 + this.bacthFillResponseWithCache(results, batchRecallRequests.size());
  41 + //3、返回结果
  42 + return results;
  43 + }
  44 +
  45 + @Override
  46 + protected boolean useEhCache() {
  47 + return false;
  48 + }
  49 +
  50 + @Override
  51 + protected Map<RecallRequest, SknBaseInfoResponse> queryMissCacheRequestResults(List<BatchBrandProductRequestResponse> missCacheRequests) {
  52 + Map<RecallRequest, SknBaseInfoResponse> results = new HashMap<>();
  53 + if (missCacheRequests == null || missCacheRequests.isEmpty()) {
  54 + return results;
  55 + }
  56 + List<String> includeFields = Arrays.asList(ProductIndexEsField.productId,ProductIndexEsField.productSkn,ProductIndexEsField.brandId,ProductIndexEsField.productFeatureFactor,ProductIndexEsField.heatValue);
  57 + List<SearchParam> searchParams = new ArrayList<>();
  58 + for (BatchBrandProductRequestResponse requestResponse : missCacheRequests) {
  59 + SearchParam searchParam = requestResponse.getRequest().searchParam();
  60 + searchParam.setIncludeFields(includeFields);
  61 + searchParams.add(searchParam);
  62 + }
  63 + List<SearchResult> searchResults = searchCommonService.doMutiSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParams);
  64 +
  65 + for (int i = 0; i < missCacheRequests.size(); i++) {
  66 + RecallRequest request = missCacheRequests.get(i).getRequest();
  67 + SearchResult searchResult = searchResults.get(i);
  68 + SknBaseInfoResponse response = this.buildResponse(searchResult);
  69 + results.put(request,response);
  70 + }
  71 +
  72 + return null;
  73 + }
  74 +
  75 + private SknBaseInfoResponse buildResponse(SearchResult searchResult) {
  76 + List<Map<String, Object>> productList = searchResult.getResultList();
  77 + List<Integer> recallSknList = new ArrayList<>();
  78 + //1、构建结果
  79 + for (Map<String, Object> productInfo : productList) {
  80 + Integer productSkn = MapUtils.getInteger(productInfo, ProductIndexEsField.productSkn, 0);
  81 + recallSknList.add(productSkn);
  82 + }
  83 + return null;//new RecallResponse(searchResult.getTotal(),recallSknList);
  84 + }
  85 +}
  1 +package com.yoho.search.service.scene.activity;
  2 +
  3 +import com.yoho.search.base.utils.Transfer;
  4 +import com.yoho.search.cache.model.AbstractCacheRequestResponse;
  5 +import com.yoho.search.service.recall.models.req.RecallRequest;
  6 +import com.yoho.search.service.recall.models.req.SknBaseInfoResponse;
  7 +
  8 +public class BatchBrandProductRequestResponse extends AbstractCacheRequestResponse<RecallRequest, SknBaseInfoResponse> {
  9 + public BatchBrandProductRequestResponse(RecallRequest request) {
  10 + super(request);
  11 + }
  12 +
  13 + @Override
  14 + public Transfer<String, SknBaseInfoResponse> getToResponseTransfer() {
  15 + return null;
  16 + }
  17 +
  18 + @Override
  19 + public Transfer<SknBaseInfoResponse, String> getFromResponseTransfer() {
  20 + return null;
  21 + }
  22 +}
  1 +package com.yoho.search.service.scene.activity;
  2 +
  3 +import com.yoho.search.base.utils.ProductIndexEsField;
  4 +import com.yoho.search.cache.CacheTimeConstants;
  5 +import com.yoho.search.service.recall.beans.strategy.StrategyEnum;
  6 +import com.yoho.search.service.recall.beans.strategy.impls.CommonHeatValueStrategy;
  7 +import org.elasticsearch.index.query.BoolQueryBuilder;
  8 +import org.elasticsearch.index.query.QueryBuilder;
  9 +import org.elasticsearch.index.query.QueryBuilders;
  10 +import org.elasticsearch.search.sort.SortBuilder;
  11 +
  12 +public class BrandHeatValueStrategy extends CommonHeatValueStrategy {
  13 + protected Integer brandId;
  14 +
  15 + public BrandHeatValueStrategy(int size, Integer brandId) {
  16 + super(size);
  17 + this.brandId = brandId;
  18 + }
  19 +
  20 +
  21 + //todo
  22 + @Override
  23 + public StringBuilder defaultStrategyKey() {
  24 + return null;
  25 + }
  26 +
  27 +
  28 + @Override
  29 + public StrategyEnum strategtEnum() {
  30 + return super.strategtEnum();
  31 + }
  32 +
  33 + @Override
  34 + public QueryBuilder extendFilter() {
  35 + BoolQueryBuilder filter = QueryBuilders.boolQuery();
  36 + filter.must(QueryBuilders.termQuery(ProductIndexEsField.brandId, brandId));
  37 + return filter;
  38 + }
  39 +
  40 + @Override
  41 + public SortBuilder<?> sortBuilder() {
  42 + return super.sortBuilder();
  43 + }
  44 +
  45 + @Override
  46 + public int size() {
  47 + return super.size();
  48 + }
  49 +
  50 + @Override
  51 + public int cacheTimeInMinute() {
  52 + return CacheTimeConstants.CACHE_60_MINUTE;
  53 + }
  54 +
  55 + //todo
  56 + @Override
  57 + public String strategyCacheKey() {
  58 + return super.strategyCacheKey();
  59 + }
  60 +}