...
|
...
|
@@ -2,21 +2,17 @@ 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.base.utils.ProductIndexEsField;
|
|
|
import com.yoho.search.cache.beans.AbstractCacheBean;
|
|
|
import com.yoho.search.core.personalized.models.PersonalizedSearch;
|
|
|
import com.yoho.search.core.personalized.models.UserPersonalFactorRspNew;
|
|
|
import com.yoho.search.service.recall.beans.helper.StrategyHelper;
|
|
|
import com.yoho.search.service.recall.beans.persional.ProductFeatureFactorComponent;
|
|
|
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.StrategyEnum;
|
|
|
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.UserFeatureFactor;
|
|
|
import com.yoho.search.service.recall.models.req.RecallRequest;
|
|
|
import com.yoho.search.service.scene.shopbrand.AggProductResponse;
|
|
|
import com.yoho.search.service.scorer.personal.PersonalVectorFeatureSearch;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
...
|
...
|
@@ -28,7 +24,7 @@ import java.util.stream.Collectors; |
|
|
public class AggBrandProductCacheBean extends AbstractCacheBean<BrandProductRequest, BrandProductResponse, BrandProductRequestResponse> {
|
|
|
|
|
|
@Autowired
|
|
|
private AggBrandService aggBrandService;
|
|
|
private AggBrandListService aggBrandService;
|
|
|
@Autowired
|
|
|
private UserPersionalFactorComponent userComponent;
|
|
|
@Autowired
|
...
|
...
|
@@ -72,9 +68,10 @@ public class AggBrandProductCacheBean extends AbstractCacheBean<BrandProductRequ |
|
|
* @return
|
|
|
*/
|
|
|
private BrandProductResponse doRealRecall(BrandProductRequest brandProductRequest) {
|
|
|
BrandProductResponse response = new BrandProductResponse();
|
|
|
//1 获取个性化的和非个性化的brandId viewNum个
|
|
|
List<AggBrand> aggBrands = aggBrandService.aggBrands(brandProductRequest.getParamQueryFilter());
|
|
|
if (org.springframework.util.CollectionUtils.isEmpty(aggBrands)) {
|
|
|
if (aggBrands == null || aggBrands.isEmpty()) {
|
|
|
return null;
|
|
|
}
|
|
|
List<Integer> aggBrandIds = aggBrands.stream().map(AggBrand::getBrandId).collect(Collectors.toList());
|
...
|
...
|
@@ -86,53 +83,64 @@ public class AggBrandProductCacheBean extends AbstractCacheBean<BrandProductRequ |
|
|
if (userPersonalbrandIds.size() < brandProductRequest.getBrandCount()) {
|
|
|
aggBrandIds.removeAll(userPersonalbrandIds);
|
|
|
aggBrandIds = CollectionUtils.safeSubList(aggBrandIds, 0, brandProductRequest.getBrandCount() - userPersonalbrandIds.size());
|
|
|
userPersonalbrandIds.addAll(aggBrandIds);
|
|
|
}
|
|
|
|
|
|
//2、获取召回结果
|
|
|
List<BatchBrandProductRequestResponse> brandProductList = batchRecall(brandProductRequest, userPersonalbrandIds, aggBrandIds);
|
|
|
|
|
|
if (brandProductRequest.hasUidOrUdid()) {
|
|
|
doCalScoreAndSort(brandProductList, brandProductRequest.getUid(), brandProductRequest.getBrandCount());
|
|
|
List<BatchBrandProductRequestResponse> brandProductListList = batchRecall(brandProductRequest, userPersonalbrandIds);
|
|
|
Map<Integer, List<BrandProduct>> recallResultMap = new HashMap<>();
|
|
|
for (BatchBrandProductRequestResponse requestResponse : brandProductListList) {
|
|
|
if (requestResponse.getResponse() != null && !org.springframework.util.CollectionUtils.isEmpty(requestResponse.getResponse().getProductList())) {
|
|
|
Integer brandId = ((BrandHeatValueStrategy)requestResponse.getRequest().strategy()).getBrandId();
|
|
|
List<BrandProduct> brandProductList = requestResponse.getResponse().getProductList();
|
|
|
recallResultMap.put(brandId, brandProductList);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
UserFeatureFactor userFeatureFactor = brandProductRequest.getUid() <= 0 ? null : getUserFeatureFactor(brandProductRequest.getUid());
|
|
|
doCalScoreAndSort(recallResultMap, userFeatureFactor);
|
|
|
//直接截取
|
|
|
List<BrandProduct> recallSknList = new ArrayList<>();
|
|
|
int productNum = brandProductRequest.getBrandProductCount();
|
|
|
for (Map.Entry<Integer, List<BrandProduct>> brandProductList : recallResultMap.entrySet()){
|
|
|
recallSknList.addAll(CollectionUtils.safeSubList(brandProductList.getValue(), 0, productNum));
|
|
|
}
|
|
|
if (!org.springframework.util.CollectionUtils.isEmpty(recallSknList)) {
|
|
|
doCalScoreAndSort(recallSknList, userFeatureFactor);
|
|
|
}
|
|
|
recallSknList = CollectionUtils.safeSubList(recallSknList, 0, brandProductRequest.getBrandCount());
|
|
|
response.setTotal(recallSknList.size());
|
|
|
response.setProductList(recallSknList);
|
|
|
return response;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
private void doCalScoreAndSort(List<BrandProduct> productList, UserFeatureFactor userFeatureFactor) {
|
|
|
for (BrandProduct product : productList) {
|
|
|
double score = productFeatureFactorComponent.calProductFeatureFactor(userFeatureFactor, product.getProductFeatureFactor());
|
|
|
if (score == 0) {
|
|
|
score = (double)product.getHeatValue()/ 100;
|
|
|
}
|
|
|
product.setScore(score);
|
|
|
}
|
|
|
Collections.sort(productList, (o1, o2) -> o2.getScore().compareTo(o1.getScore()));
|
|
|
}
|
|
|
|
|
|
private void doCalScoreAndSort(Map<Integer, List<BrandProduct>> recallResultMap, UserFeatureFactor userFeatureFactor) {
|
|
|
//2、计算相关性
|
|
|
for (Map.Entry<Integer, List<BrandProduct>> brandProductList : recallResultMap.entrySet()){
|
|
|
if (brandProductList != null && !org.springframework.util.CollectionUtils.isEmpty(brandProductList.getValue())) {
|
|
|
List<BrandProduct> productList = brandProductList.getValue();
|
|
|
doCalScoreAndSort(productList, userFeatureFactor);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 粗排-按相关性计算得分,并按得分排序
|
|
|
*
|
|
|
* @param sknResultList
|
|
|
* @param uid
|
|
|
*/
|
|
|
private void doCalScoreAndSort(List<BatchBrandProductRequestResponse> sknResultList, int uid, int pageSize) {
|
|
|
private UserFeatureFactor getUserFeatureFactor(int uid) {
|
|
|
//1、获取用户向量
|
|
|
Map<String, String> paramMap = new HashMap<>();
|
|
|
paramMap.put("uid", "" + uid);
|
|
|
PersonalizedSearch personalizedSearch = personalVectorFeatureSearch.queryPersonalizedSearch(paramMap);
|
|
|
UserFeatureFactor userFeatureFactor = new UserFeatureFactor(personalizedSearch);
|
|
|
//2、计算相关性
|
|
|
int recommendSknIndex = 10000;
|
|
|
|
|
|
for (BatchBrandProductRequestResponse brandProduct : sknResultList){
|
|
|
AggProductResponse aggProductResponse = brandProduct.getResponse();
|
|
|
List<Map<String, Object>> productList = aggProductResponse.getProduct_list();
|
|
|
|
|
|
|
|
|
for (Map<String, Object> product : productList) {
|
|
|
double score = 0d;
|
|
|
score = productFeatureFactorComponent.calProductFeatureFactor(userFeatureFactor, product.get(ProductIndexEsField.productFeatureFactor).toString());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
return new UserFeatureFactor(personalizedSearch);
|
|
|
}
|
|
|
|
|
|
|
|
|
private List<Integer> buildUserPersonalBrandIds(List<Integer> aggBrandIds, UserPersonalFactorRspNew userFactor, int count) {
|
|
|
List<Integer> result = new ArrayList<>();
|
|
|
double userBrandVectorNorm = Word2VectorCalculator.getVectorListNorm(userFactor.getBrandVectorW2v());
|
...
|
...
|
@@ -156,21 +164,15 @@ public class AggBrandProductCacheBean extends AbstractCacheBean<BrandProductRequ |
|
|
return result;
|
|
|
}
|
|
|
|
|
|
private List<BatchBrandProductRequestResponse> batchRecall(BrandProductRequest brandProductRequest, List<Integer> userPersonalbrandIds, List<Integer> aggBrandIds) {
|
|
|
|
|
|
List<Integer> brandIds = new ArrayList<>(userPersonalbrandIds);
|
|
|
brandIds.addAll(aggBrandIds);
|
|
|
private List<BatchBrandProductRequestResponse> batchRecall(BrandProductRequest brandProductRequest, List<Integer> brandIds) {
|
|
|
int brandProductCount = brandProductRequest.getBrandProductCount() + 20;
|
|
|
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());
|
|
|
|
|
|
List<BatchBrandProductRequestResponse> requestResponses = batchBrandProductCacheBean.batchRecallAndCache(brandRequests);
|
|
|
return requestResponses;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
...
|
...
|
|