Authored by zhaojun2

brand product

package com.yoho.search.service.scene.activity;
import com.yoho.search.base.helper.Word2VectorCalculator;
import com.yoho.search.base.utils.CollectionUtils;
import com.yoho.search.cache.beans.AbstractCacheBean;
import com.yoho.search.core.personalized.models.UserPersonalFactorRspNew;
import com.yoho.search.service.recall.beans.persional.UserPersionalFactorComponent;
import com.yoho.search.service.recall.beans.strategy.IStrategy;
import com.yoho.search.service.recall.beans.strategy.impls.SortBrandHeatValueStrategy;
import com.yoho.search.service.recall.beans.vector.BrandVectorCacheBean;
import com.yoho.search.service.recall.models.common.ParamQueryFilter;
import com.yoho.search.service.recall.models.personal.BrandVectorScore;
import com.yoho.search.service.recall.models.personal.UserPersonalFactor;
import com.yoho.search.service.recall.models.req.RecallRequest;
import com.yoho.search.service.recall.models.req.RecallRequestResponse;
import com.yoho.search.service.recall.models.req.UserRecallRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
@Component
public class AggBrandProductCacheBean extends AbstractCacheBean<BrandProductRequest, BrandProductResponse, BrandProductRequestResponse> {
@Autowired
private AggBrandService aggBrandService;
@Autowired
private UserPersionalFactorComponent userComponent;
@Autowired
private BrandVectorCacheBean brandVectorCacheBean;
@Autowired
private BatchBrandProductCacheBean batchBrandProductCacheBean;
/**
* 入口
* @return
*/
public BrandProductResponse queryBrandProductResult(BrandProductRequest brandProductRequest) {
BrandProductRequestResponse brandProductRequestResponse = new BrandProductRequestResponse(brandProductRequest);
bacthFillResponseWithCache(brandProductRequestResponse, false);
return brandProductRequestResponse.getResponse();
}
@Override
protected boolean useEhCache() {
return false;
}
@Override
protected Map<BrandProductRequest, BrandProductResponse> queryMissCacheRequestResults(List<BrandProductRequestResponse> missCacheRequests) {
Map<BrandProductRequest, BrandProductResponse> results = new HashMap<>();
for (BrandProductRequestResponse request : missCacheRequests) {
BrandProductResponse response = doRealRecall(request.getRequest());
results.put(request.getRequest(), response);
}
return results;
}
/**
* 真正的召回入口
*
* @param brandProductRequest
* @return
*/
private BrandProductResponse doRealRecall(BrandProductRequest brandProductRequest) {
//1 获取个性化的和非个性化的brandId viewNum个
List<AggBrand> aggBrands = aggBrandService.aggBrands(brandProductRequest.getParamQueryFilter());
if (org.springframework.util.CollectionUtils.isEmpty(aggBrands)) {
return null;
}
List<Integer> aggBrandIds = aggBrands.stream().map(AggBrand::getBrandId).collect(Collectors.toList());
List<Integer> userPersonalbrandIds = new ArrayList<>();
if (brandProductRequest.hasUidOrUdid()) {
UserPersonalFactorRspNew userFactor = userComponent.queryUserPersionalFactor(brandProductRequest.getUid(), brandProductRequest.getUdid(), null);
userPersonalbrandIds = buildUserPersonalBrandIds(aggBrandIds, userFactor, brandProductRequest.getBrandCount());
}
if (userPersonalbrandIds.size() < brandProductRequest.getBrandCount()) {
aggBrandIds.removeAll(userPersonalbrandIds);
aggBrandIds = CollectionUtils.safeSubList(aggBrandIds, 0, brandProductRequest.getBrandCount() - userPersonalbrandIds.size());
}
//2、获取召回结果
batchRecall(brandProductRequest, userPersonalbrandIds, aggBrandIds);
return null;
}
private List<Integer> buildUserPersonalBrandIds(List<Integer> aggBrandIds, UserPersonalFactorRspNew userFactor, int count) {
List<Integer> result = new ArrayList<>();
double userBrandVectorNorm = Word2VectorCalculator.getVectorListNorm(userFactor.getBrandVectorW2v());
List<BrandVectorScore> brandVectorScores = new ArrayList<>();
for (Integer brandId : aggBrandIds) {
List<Double> brandVector = brandVectorCacheBean.queryBrandVector(brandId, false);
if (brandVector == null || brandVector.isEmpty()) {
continue;
}
double score = Word2VectorCalculator.calScore(userFactor.getBrandVectorW2v(), userBrandVectorNorm, brandVector);
brandVectorScores.add(new BrandVectorScore(brandId, score));
}
if (brandVectorScores != null && !brandVectorScores.isEmpty()){
Collections.sort(brandVectorScores, (o1, o2) -> o2.getScore().compareTo(o1.getScore()));//得分高的排在前面
brandVectorScores = CollectionUtils.safeSubList(brandVectorScores, 0, count);
for (BrandVectorScore brandVectorScore : brandVectorScores) {
result.add(brandVectorScore.getBrandId());
}
}
return result;
}
private List<BrandProductRequestResponse> batchRecall(BrandProductRequest brandProductRequest, List<Integer> userPersonalbrandIds, List<Integer> aggBrandIds) {
List<Integer> brandIds = new ArrayList<>(userPersonalbrandIds);
brandIds.addAll(aggBrandIds);
int brandProductCount = brandProductRequest.getBrandProductCount() + 10;
ParamQueryFilter paramQueryFilter = brandProductRequest.getParamQueryFilter();
List<RecallRequest> brandRequests = brandIds.stream().map(brandId -> {
IStrategy strategy = new BrandHeatValueStrategy(brandId, brandProductCount);
return new RecallRequest(paramQueryFilter, strategy);
}).collect(Collectors.toList());
return null;
}
}
... ...
package com.yoho.search.service.scene.activity;
import com.yoho.search.common.SearchCommonService;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.helper.*;
import com.yoho.search.service.recall.beans.builder.UserRecallRequestBuilder;
import com.yoho.search.service.recall.beans.persional.UserPersionalFactorComponent;
import com.yoho.search.service.recall.beans.vector.BrandVectorCacheBean;
import com.yoho.search.service.recall.models.common.ParamQueryFilter;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
... ... @@ -28,7 +24,7 @@ public class AggBrandProductListService implements ApplicationEventPublisherAwar
private ApplicationEventPublisher publisher;
@Autowired
private BrandProductCacheBean brandProductCacheBean;
private AggBrandProductCacheBean brandProductCacheBean;
@Autowired
private SearchQueryHelper searchServiceHelepr;
... ...
... ... @@ -14,6 +14,7 @@ import com.yoho.search.cache.model.CacheObject;
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.service.helper.SearchParamHelper;
import com.yoho.search.service.recall.models.common.ParamQueryFilter;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
... ... @@ -36,15 +37,14 @@ public class AggBrandService extends AbstractPageComponent<List<AggBrand>> {
@Autowired
private SearchCommonService searchCommonService;
@Autowired
private SearchParamHelper searchParamHelper;
public List<AggBrand> aggBrands(ParamQueryFilter paramQueryFilter) {
RedisKeyBuilder redisKeyBuilder = this.genRedisKeyBuilder(paramQueryFilter);
List<AggBrand> value = queryFromCache(redisKeyBuilder);
if (CollectionUtils.isEmpty(value)) {
// value = getFromEs(searchParam);
value = getFromEs(searchParamHelper.buildSearchParam(paramQueryFilter));
if (!CollectionUtils.isEmpty(value)) {
addToRedisAndEhcache(redisKeyBuilder, value);
}
... ...
package com.yoho.search.service.scene.activity;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.cache.beans.AbstractCacheBean;
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.service.recall.models.req.RecallRequest;
import com.yoho.search.service.recall.models.req.RecallRequestResponse;
import com.yoho.search.service.recall.models.req.RecallResponse;
import com.yoho.search.service.recall.models.req.SknBaseInfoResponse;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
public class BatchBrandProductCacheBean extends AbstractCacheBean<RecallRequest, SknBaseInfoResponse, BatchBrandProductRequestResponse> {
@Autowired
private SearchCommonService searchCommonService;
/**
* 批量召回入口
*
* @param batchRecallRequests
* @return
*/
public List<BatchBrandProductRequestResponse> batchRecallAndCache(final List<RecallRequest> batchRecallRequests) {
//1、构造请求
final List<BatchBrandProductRequestResponse> results = new ArrayList<>();
for (RecallRequest request : batchRecallRequests) {
results.add(new BatchBrandProductRequestResponse(request));
}
//2、执行查询
this.bacthFillResponseWithCache(results, batchRecallRequests.size());
//3、返回结果
return results;
}
@Override
protected boolean useEhCache() {
return false;
}
@Override
protected Map<RecallRequest, SknBaseInfoResponse> queryMissCacheRequestResults(List<BatchBrandProductRequestResponse> missCacheRequests) {
Map<RecallRequest, SknBaseInfoResponse> results = new HashMap<>();
if (missCacheRequests == null || missCacheRequests.isEmpty()) {
return results;
}
List<String> includeFields = Arrays.asList(ProductIndexEsField.productId,ProductIndexEsField.productSkn,ProductIndexEsField.brandId,ProductIndexEsField.productFeatureFactor,ProductIndexEsField.heatValue);
List<SearchParam> searchParams = new ArrayList<>();
for (BatchBrandProductRequestResponse requestResponse : missCacheRequests) {
SearchParam searchParam = requestResponse.getRequest().searchParam();
searchParam.setIncludeFields(includeFields);
searchParams.add(searchParam);
}
List<SearchResult> searchResults = searchCommonService.doMutiSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParams);
for (int i = 0; i < missCacheRequests.size(); i++) {
RecallRequest request = missCacheRequests.get(i).getRequest();
SearchResult searchResult = searchResults.get(i);
SknBaseInfoResponse response = this.buildResponse(searchResult);
results.put(request,response);
}
return null;
}
private SknBaseInfoResponse buildResponse(SearchResult searchResult) {
List<Map<String, Object>> productList = searchResult.getResultList();
List<Integer> recallSknList = new ArrayList<>();
//1、构建结果
for (Map<String, Object> productInfo : productList) {
Integer productSkn = MapUtils.getInteger(productInfo, ProductIndexEsField.productSkn, 0);
recallSknList.add(productSkn);
}
return null;//new RecallResponse(searchResult.getTotal(),recallSknList);
}
}
... ...
package com.yoho.search.service.scene.activity;
import com.yoho.search.base.utils.Transfer;
import com.yoho.search.cache.model.AbstractCacheRequestResponse;
import com.yoho.search.service.recall.models.req.RecallRequest;
import com.yoho.search.service.recall.models.req.SknBaseInfoResponse;
public class BatchBrandProductRequestResponse extends AbstractCacheRequestResponse<RecallRequest, SknBaseInfoResponse> {
public BatchBrandProductRequestResponse(RecallRequest request) {
super(request);
}
@Override
public Transfer<String, SknBaseInfoResponse> getToResponseTransfer() {
return null;
}
@Override
public Transfer<SknBaseInfoResponse, String> getFromResponseTransfer() {
return null;
}
}
... ...
package com.yoho.search.service.scene.activity;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.cache.CacheTimeConstants;
import com.yoho.search.service.recall.beans.strategy.StrategyEnum;
import com.yoho.search.service.recall.beans.strategy.impls.CommonHeatValueStrategy;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilder;
public class BrandHeatValueStrategy extends CommonHeatValueStrategy {
protected Integer brandId;
public BrandHeatValueStrategy(int size, Integer brandId) {
super(size);
this.brandId = brandId;
}
//todo
@Override
public StringBuilder defaultStrategyKey() {
return null;
}
@Override
public StrategyEnum strategtEnum() {
return super.strategtEnum();
}
@Override
public QueryBuilder extendFilter() {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
filter.must(QueryBuilders.termQuery(ProductIndexEsField.brandId, brandId));
return filter;
}
@Override
public SortBuilder<?> sortBuilder() {
return super.sortBuilder();
}
@Override
public int size() {
return super.size();
}
@Override
public int cacheTimeInMinute() {
return CacheTimeConstants.CACHE_60_MINUTE;
}
//todo
@Override
public String strategyCacheKey() {
return super.strategyCacheKey();
}
}
... ...