Authored by hugufei

Merge branch 'wn_customize_tag'

... ... @@ -133,6 +133,7 @@ public class SearchRequestParams {
public static final String SHOPS_PARAM_CUSTOMIZE_TAG = "customize_tag";
public static final String SHOPS_PARAM_CUSTOMIZE_TAG_NEW = "customize_tag_new";
//Promotion index field
public static final String PROMOTIONINDEX_ISDEL = "isDel";
... ...
package com.yoho.search.service.aggregations.impls;
import com.yoho.search.base.utils.ConvertUtils;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.common.SearchRequestParams;
import com.yoho.search.core.es.agg.AbstractAggregation;
import com.yoho.search.service.index.ActivityTagBaseService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.filter.InternalFilter;
import org.elasticsearch.search.aggregations.bucket.nested.InternalNested;
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.LongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Created by wangnan on 2017/9/12.
*/
public class ActivityTagAggregation extends AbstractAggregation {
private Map<String, String> paramMap;
private static String NESTED_PATH = ProductIndexEsField.customizeTags;
private static String SUB_AGG_NAME = "subCustomizeTagAgg";
private static int AGG_COUNT = 100;
private ActivityTagBaseService activityTagBaseService;
ActivityTagAggregation(ActivityTagBaseService activityTagBaseService, Map<String, String> paramMap) {
this.paramMap = paramMap;
this.activityTagBaseService = activityTagBaseService;
}
@Override
public String aggName() {
return "customizeTagAgg";
}
@Override
public String filterName() {
return "customizeTagFilter";
}
@Override
public AbstractAggregationBuilder<?> getBuilder() {
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
if (paramMap.containsKey(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG)) {
int[] ids = ConvertUtils.stringToIntArray(paramMap.get(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG), ",");
boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.customizeTagsId, ids));
}
AbstractAggregationBuilder<NestedAggregationBuilder> nestedAggregationBuilder = AggregationBuilders.nested(aggName(), NESTED_PATH)
.subAggregation(AggregationBuilders.filter(filterName(), boolFilter)
.subAggregation(AggregationBuilders.terms(SUB_AGG_NAME).field(ProductIndexEsField.customizeTagsId).size(AGG_COUNT).order(Terms.Order.count(false))));
return nestedAggregationBuilder;
}
@Override
public Object getAggregationResponseMap(Map<String, Aggregation> aggMaps) {
InternalNested aggregation = (InternalNested) aggMaps.get(aggName());
if (CollectionUtils.isEmpty(aggregation.getAggregations().asList())) {
return new ArrayList<>();
}
InternalFilter filter = (InternalFilter) aggregation.getAggregations().asList().get(0);
List<LongTerms.Bucket> longTerms = ((LongTerms) filter.getAggregations().asList().get(0)).getBucketsInternal();
Set<String> tagIdSet = longTerms.stream().map(e -> e.getKeyAsNumber().intValue() + "").collect(Collectors.toSet());
if (CollectionUtils.isEmpty(tagIdSet)) {
return new ArrayList<>();
}
return activityTagBaseService.getTagListByIds(tagIdSet);
}
}
\ No newline at end of file
... ...
... ... @@ -35,7 +35,9 @@ public class AggregationFactory {
@Autowired
private ProductIndexBaseService productIndexBaseService;
@Autowired
private CustomizeTagBaseService customizeTagBaseService;
private ActivityTagBaseService activityTagBaseService;
@Autowired
private CustomizeTagBaseService customizeTagBaseService;
@Autowired
private PromotionIndexBaseService promotionIndexBaseService;
@Autowired
... ... @@ -145,10 +147,14 @@ public class AggregationFactory {
return new ShopAggregation(shopsIndexBaseService, aggCount);
}
public IAggregation getCustomizeTagAggregation(Map<String, String> paramMap) {
return new CustomizeTagAggregation(customizeTagBaseService, paramMap);
public IAggregation getActivityTagAggregation(Map<String, String> paramMap) {
return new ActivityTagAggregation(activityTagBaseService, paramMap);
}
public IAggregation getCustomizeTagAggregation(Map<String, String> paramMap) {
return new CustomizeTagAggregation(customizeTagBaseService, paramMap);
}
public IAggregation getShopAndSknAggregation(int aggCount) {
return new ShopAndSknAggregation(aggCount);
}
... ...
package com.yoho.search.service.aggregations.impls;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.filter.InternalFilter;
import org.elasticsearch.search.aggregations.bucket.nested.InternalNested;
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.LongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.springframework.util.CollectionUtils;
import com.yoho.search.base.utils.ConvertUtils;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.core.es.agg.AbstractAggregation;
import com.yoho.search.common.SearchRequestParams;
import com.yoho.search.service.index.CustomizeTagBaseService;
/**
* Created by wangnan on 2017/9/12.
*/
public class CustomizeTagAggregation extends AbstractAggregation {
private Map<String, String> paramMap;
private static String NESTED_PATH = ProductIndexEsField.customizeTags;
private static String SUB_AGG_NAME = "subCustomizeTagAgg";
private static int AGG_COUNT = 100;
private CustomizeTagBaseService customizeTagBaseService;
CustomizeTagAggregation(CustomizeTagBaseService colorIndexBaseService, Map<String, String> paramMap) {
this.paramMap = paramMap;
this.customizeTagBaseService = colorIndexBaseService;
}
@Override
public String aggName() {
return "customizeTagAgg";
}
@Override
public String filterName() {
return "customizeTagFilter";
}
@Override
public AbstractAggregationBuilder<?> getBuilder() {
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
if (paramMap.containsKey(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG)) {
int[] ids = ConvertUtils.stringToIntArray(paramMap.get(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG), ",");
boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.customizeTagsId, ids));
}
AbstractAggregationBuilder<NestedAggregationBuilder> nestedAggregationBuilder = AggregationBuilders.nested(aggName(), NESTED_PATH)
.subAggregation(AggregationBuilders.filter(filterName(), boolFilter)
.subAggregation(AggregationBuilders.terms(SUB_AGG_NAME).field(ProductIndexEsField.customizeTagsId).size(AGG_COUNT).order(Terms.Order.count(false))));
return nestedAggregationBuilder;
}
@Override
public Object getAggregationResponseMap(Map<String, Aggregation> aggMaps) {
InternalNested aggregation = (InternalNested) aggMaps.get(aggName());
if (CollectionUtils.isEmpty(aggregation.getAggregations().asList())) {
return new ArrayList<>();
}
InternalFilter filter = (InternalFilter) aggregation.getAggregations().asList().get(0);
List<LongTerms.Bucket> longTerms = ((LongTerms) filter.getAggregations().asList().get(0)).getBucketsInternal();
Set<String> tagIdSet = longTerms.stream().map(e -> e.getKeyAsNumber().intValue() + "").collect(Collectors.toSet());
if (CollectionUtils.isEmpty(tagIdSet)) {
return new ArrayList<>();
}
return customizeTagBaseService.getTagListByIds(tagIdSet);
}
package com.yoho.search.service.aggregations.impls;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.core.es.agg.AbstractAggregation;
import com.yoho.search.service.index.CustomizeTagBaseService;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Created by wangnan on 2017/9/12.
*/
public class CustomizeTagAggregation extends AbstractAggregation {
private static int AGG_COUNT = 500;
private CustomizeTagBaseService customizeTagBaseService;
CustomizeTagAggregation(CustomizeTagBaseService customizeBaseService, Map<String, String> paramMap) {
this.customizeTagBaseService = customizeBaseService;
}
@Override
public String aggName() {
return "customizeTagAggNew";
}
@Override
public String filterName() {
return "customizeTagFilterNew";
}
@Override
public AbstractAggregationBuilder<?> getBuilder() {
return AggregationBuilders.terms(aggName()).field(ProductIndexEsField.poolIds).size(AGG_COUNT);
}
@Override
public Object getAggregationResponseMap(Map<String, Aggregation> aggMaps) {
try {
MultiBucketsAggregation aggregation = this.getAggregation(aggMaps);
if (aggregation == null) {
return null;
}
List<String> poolIdList = new ArrayList<>();
Iterator<? extends MultiBucketsAggregation.Bucket> itPoolIdAgg = aggregation.getBuckets().iterator();
while (itPoolIdAgg.hasNext()) {
MultiBucketsAggregation.Bucket itPoolId = itPoolIdAgg.next();
for (String poolId : itPoolId.getKeyAsString().split(",")) {
poolIdList.add(poolId);
}
}
return customizeTagBaseService.getTagListByIds(poolIdList);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return new Object();
}
}
\ No newline at end of file
... ...
package com.yoho.search.service.helper;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.aop.productlist.ProductListWithSkn;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.aop.productlist.ProductListWithSkn;
import com.yoho.search.service.recall.beans.strategy.NotRecallTypeEnum;
import com.yoho.search.service.index.CustomizeTagBaseService;
import com.yoho.search.service.index.ProductIndexBaseService;
import com.yoho.search.service.index.ProductPricePlanIndexBaseService;
import com.yoho.search.service.index.promotion.PromotionIndexBaseService;
import com.yoho.search.service.index.promotion.PromotionPriceService;
import com.yoho.search.service.recall.beans.strategy.NotRecallTypeEnum;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -38,6 +39,8 @@ public class ProductListHelper {
private PromotionIndexBaseService promotionIndexBaseService;
@Autowired
private PromotionPriceService promotionPriceService;
@Autowired
private CustomizeTagBaseService customizeTagBaseService;
public SearchParam buildProductListSearchParam(Map<String, String> paramMap, boolean needPersional) throws Exception {
return this.innerBuildProductListSearchParam(paramMap, needPersional, false);
... ... @@ -117,6 +120,7 @@ public class ProductListHelper {
productPricePlanIndexBaseService.fillProductPricePlan(productReturnInfoList);
promotionIndexBaseService.fillPromotionTag(productReturnInfoList);
promotionPriceService.fillPromotionPrice(productReturnInfoList);
customizeTagBaseService.fillCustomizeTag(productReturnInfoList);
return productReturnInfoList;
}
... ...
... ... @@ -382,7 +382,7 @@ public class SearchCommonHelper {
* @param paramMap
* @return
*/
public BoolQueryBuilder getCustomizeTagBuilder(Map<String, String> paramMap) {
public BoolQueryBuilder getActivityTagBuilder(Map<String, String> paramMap) {
if (paramMap.containsKey(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG) && StringUtils.isNotBlank(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG)) {
int[] ids = ConvertUtils.stringToIntArray(paramMap.get(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG), ",");
BoolQueryBuilder nestedBoolFilter = QueryBuilders.boolQuery();
... ... @@ -391,4 +391,14 @@ public class SearchCommonHelper {
}
return null;
}
/**
* 自定义标签过滤
*/
public void getCustomizeTagBuilder(Map<String, String> paramMap, BoolQueryBuilder boolFilter) {
if (paramMap.containsKey(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG_NEW) && StringUtils.isNotBlank(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG_NEW)) {
int[] poolIds = ConvertUtils.stringToIntArray(paramMap.get(SearchRequestParams.SHOPS_PARAM_CUSTOMIZE_TAG_NEW), ",");
boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.poolIds, poolIds));
}
}
}
... ...
... ... @@ -326,12 +326,15 @@ public class SearchQueryHelper {
boolFilter.must(QueryBuilders.nestedQuery(ProductIndexEsField.activities, activitiesTermsBuilder, ScoreMode.None));
}
// 自定义标签
BoolQueryBuilder customizeTagsTermsBuilder = searchCommonHelper.getCustomizeTagBuilder(paramMap);
// 自定义标签:旧
BoolQueryBuilder customizeTagsTermsBuilder = searchCommonHelper.getActivityTagBuilder(paramMap);
if (customizeTagsTermsBuilder != null) {
boolFilter.must(QueryBuilders.nestedQuery(ProductIndexEsField.customizeTags, customizeTagsTermsBuilder, ScoreMode.None));
}
// 自定义标签:新
searchCommonHelper.getCustomizeTagBuilder(paramMap,boolFilter);
// 用户VIP级别过滤
if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_USER_VIP_LEVEL)) {
List<String> userVipLevels = this.getUserVipLevels(paramMap.get(SearchRequestParams.PARAM_SEARCH_USER_VIP_LEVEL));
... ...
package com.yoho.search.service.index;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.common.SearchCommonService;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* Created by wangnan on 2017/9/12.
*/
@Service
public class ActivityTagBaseService {
private final Logger logger = LoggerFactory.getLogger(getClass());
private static final String ACTIVITY_TAG_INDEX_NAME = ISearchConstants.INDEX_NAME_ACTIVITY_TAG;
@Autowired
private SearchCommonService searchCommonService;
public List<Map<String, Object>> getTagListByIds(final Collection<?> tagIds) {
List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
try {
List<Map<String, Object>> sizeEsMapList = searchCommonService.doMultiGetCommon(ACTIVITY_TAG_INDEX_NAME, tagIds);
for (Map<String, Object> sizeEsMap : sizeEsMapList) {
resultList.add(this.getTagMap(sizeEsMap));
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return resultList;
}
private Map<String, Object> getTagMap(Map<String, Object> esMap) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", MapUtils.getIntValue(esMap, "id", 0));
map.put("name", MapUtils.getString(esMap, "activityName", ""));
return map;
}
}
... ...
package com.yoho.search.service.index;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.common.SearchCommonService;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* Created by wangnan on 2017/9/12.
*/
@Service
public class CustomizeTagBaseService {
private final Logger logger = LoggerFactory.getLogger(getClass());
private static final String ACTIVITY_TAG_INDEX_NAME = ISearchConstants.INDEX_NAME_ACTIVITY_TAG;
@Autowired
private SearchCommonService searchCommonService;
public List<Map<String, Object>> getTagListByIds(final Collection<?> tagIds) {
List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
try {
List<Map<String, Object>> sizeEsMapList = searchCommonService.doMultiGetCommon(ACTIVITY_TAG_INDEX_NAME, tagIds);
for (Map<String, Object> sizeEsMap : sizeEsMapList) {
resultList.add(this.getTagMap(sizeEsMap));
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return resultList;
}
private Map<String, Object> getTagMap(Map<String, Object> esMap) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", MapUtils.getIntValue(esMap, "id", 0));
map.put("name", MapUtils.getString(esMap, "activityName", ""));
return map;
}
}
package com.yoho.search.service.index;
import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.yoho.search.base.utils.ConvertUtils;
import com.yoho.search.base.utils.DateUtil;
import com.yoho.search.base.utils.ISearchConstants;
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.dal.model.CustomizeTag;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* Created by wangnan on 2017/9/12.
*/
@Service
public class CustomizeTagBaseService {
@Autowired
private SearchCommonService searchCommonService;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private static final String CACHE_KEY = "CacheKey";
private static final String POOLID_CUSTOMIZETAG_MAP_CACHE_KEY = "poolIdCustomizeTagMapCacheKey";
private static final String PRODUCTINDEX_FIELD_POOLIDS = "pool_ids";
//Guava Cache
LoadingCache<String, JSONObject> customizeTagCache = CacheBuilder.newBuilder()
.maximumSize(30000)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build(new CacheLoader<String, JSONObject>() {
public JSONObject load(String key) {
JSONObject jsonObject = new JSONObject();
jsonObject.put(POOLID_CUSTOMIZETAG_MAP_CACHE_KEY, buildCustomizeTagMap());
return jsonObject;
}
});
/**
* 给列表中的每个skn加入自定义标签节点
*/
public void fillCustomizeTag(List<Map<String, Object>> productList) {
try {
//1、判断
if (CollectionUtils.isEmpty(productList)) {
return;
}
//2、获取poolId和customizeTag的map,缓存5分钟
Map<String, List<CustomizeTag>> customizeTagMap = this.getCustomizeTagMapFromCache();
if (customizeTagMap.isEmpty()) {
return;
}
//3、遍历product列表,插入customizeTag
for (Map<String, Object> productMap : productList) {
String poolIds = MapUtils.getString(productMap, PRODUCTINDEX_FIELD_POOLIDS, "");
if (StringUtils.isEmpty(poolIds)) {
continue;
}
List<JSONObject> customizeTags = this.buildCustomizeTag(poolIds, customizeTagMap);
productMap.put("customize_tag_new", customizeTags);
}
} catch (Exception e) {
logger.error(e.getMessage());
}
}
/**
* 从缓存中获取poolId->CustomizeTags映射,用于构建列表customizeTag
*/
private Map<String, List<CustomizeTag>> getCustomizeTagMapFromCache() throws Exception {
JSONObject jsonObject = customizeTagCache.get(CACHE_KEY);
Assert.isTrue(jsonObject != null, "[cache jsonObject cannot be null][fun=getCustomizeTagMapFromCache]");
return (Map<String, List<CustomizeTag>>) jsonObject.get(POOLID_CUSTOMIZETAG_MAP_CACHE_KEY);
}
/**
* 根据poolIds生成自定义标签节点
*/
private List<JSONObject> buildCustomizeTag(String poolIds, Map<String, List<CustomizeTag>> customizeTagBOMap) throws Exception {
String[] poolIdArray = poolIds.split(",");
if (poolIdArray.length == 0) {
return new ArrayList<>();
}
List<String> poolIdList = Arrays.asList(poolIdArray);
List<JSONObject> customizeTagList = new ArrayList<>();
for (String poolId : poolIdList) {
List<CustomizeTag> customizeTagBOS = customizeTagBOMap.get(poolId);
if (CollectionUtils.isEmpty(customizeTagBOS)) {
continue;
}
//按照开始时间排序
List<CustomizeTag> sortedCustomizeTagList = customizeTagBOS.stream().sorted(Comparator.comparingInt(CustomizeTag::getBeginTime).reversed()).collect(Collectors.toList());
if (CollectionUtils.isEmpty(sortedCustomizeTagList)) {
continue;
}
//取第一个
CustomizeTag customizeTag = sortedCustomizeTagList.get(0);
JSONObject tag = new JSONObject();
tag.put("id", customizeTag.getId());
tag.put("name", customizeTag.getActivityName());
tag.put("url", customizeTag.getTagUrl());
customizeTagList.add(tag);
}
return customizeTagList;
}
/**
* 构建poolId->ActivityTagBO Map
*/
private Map<String, List<CustomizeTag>> buildCustomizeTagMap() {
try {
Map<String, List<CustomizeTag>> customizeTagBOMap = new HashMap();
List<CustomizeTag> customizeTagList = getCustomizeTags(false, null);
if (CollectionUtils.isEmpty(customizeTagList)) {
return new HashMap<>();
}
for (CustomizeTag customizeTag : customizeTagList) {
String poolIds = customizeTag.getPoolId();
String[] poolIdsArray = poolIds.split(",");
if (poolIdsArray == null) {
continue;
}
for (int i = 0; i < poolIdsArray.length; i++) {
if (customizeTagBOMap.containsKey(poolIdsArray[i])) {
List<CustomizeTag> customizeTags = customizeTagBOMap.get(poolIdsArray[i]);
customizeTags.add(customizeTag);
} else {
List<CustomizeTag> customizeTags = new ArrayList<>();
customizeTags.add(customizeTag);
customizeTagBOMap.put(poolIdsArray[i], customizeTags);
}
}
}
return customizeTagBOMap;
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new HashMap<>();
}
}
/**
* 查CustomizeTag索引,可以查指定的poolId的
*/
private List<CustomizeTag> getCustomizeTags(boolean filterPoolId, String poolIdsString) throws Exception {
SearchParam searchParam = new SearchParam();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
if (filterPoolId) {
if (StringUtils.isEmpty(poolIdsString)) {
return new ArrayList<>();
}
int[] poolIds = ConvertUtils.stringToIntArray(poolIdsString, ",");
boolQueryBuilder.must(QueryBuilders.termsQuery("poolId", poolIds));
}
boolQueryBuilder.must(QueryBuilders.termQuery("status", 1));
long currentTime = DateUtil.getCurrentTimeSecond();
boolQueryBuilder.must(QueryBuilders.rangeQuery("beginTime").lt(currentTime));
boolQueryBuilder.must(QueryBuilders.rangeQuery("endTime").gt(currentTime));
searchParam.setFiter(boolQueryBuilder);
searchParam.setSize(10000);
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_CUSTOMIZE_TAG, searchParam);
if (searchResult == null || CollectionUtils.isEmpty(searchResult.getResultList())) {
return Collections.emptyList();
}
List<CustomizeTag> resultList = new ArrayList<>();
for (Map<String, Object> esMap : searchResult.getResultList()) {
if (!esMap.isEmpty()) {
resultList.add(parseCustomizeTagInfo(esMap));
}
}
return resultList;
}
/**
* CustomizeTag索引数据映射到BO
*/
private CustomizeTag parseCustomizeTagInfo(Map<String, Object> esMap) {
CustomizeTag customizeTagBO = new CustomizeTag();
customizeTagBO.setId(MapUtils.getIntValue(esMap, "id", 0));
customizeTagBO.setActivityName(MapUtils.getString(esMap, "activityName", ""));
customizeTagBO.setTagUrl(MapUtils.getString(esMap, "tagUrl", ""));
customizeTagBO.setPoolId(MapUtils.getString(esMap, "poolId", ""));
customizeTagBO.setBeforeImgUrl(MapUtils.getString(esMap, "beforeImgUrl", ""));
customizeTagBO.setAfterImgUrl(MapUtils.getString(esMap, "afterImgUrl", ""));
customizeTagBO.setBeginTime(MapUtils.getIntValue(esMap, "beginTime", 0));
customizeTagBO.setEndTime(MapUtils.getIntValue(esMap, "endTime", 0));
return customizeTagBO;
}
/**
* 用于聚合里返回自定义标签
*/
public List<Map<String, Object>> getTagListByIds(List<String> poolIdList) {
try {
String poolIdsString = poolIdList.stream().collect(Collectors.joining(","));
List<CustomizeTag> customizeTagBOList = this.getCustomizeTags(true, poolIdsString);
if (CollectionUtils.isEmpty(customizeTagBOList)) {
return new ArrayList<>();
}
List<CustomizeTag> sortedCustomizeTags = customizeTagBOList.stream().sorted(Comparator.comparingInt(CustomizeTag::getBeginTime).reversed()).collect(Collectors.toList());
if (CollectionUtils.isEmpty(sortedCustomizeTags)) {
return new ArrayList<>();
}
List<Map<String, Object>> resultList = new ArrayList<>();
sortedCustomizeTags.stream().forEach(p -> resultList.add(this.getTagMap(p)));
return resultList;
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return new ArrayList<>();
}
private Map<String, Object> getTagMap(CustomizeTag customizeTagBO) {
Map<String, Object> map = new HashMap<>();
map.put("id", customizeTagBO.getPoolId());
map.put("name", customizeTagBO.getActivityName());
map.put("beforeImgUrl", customizeTagBO.getBeforeImgUrl());
map.put("afterImgUrl", customizeTagBO.getAfterImgUrl());
return map;
}
}
... ...
... ... @@ -105,6 +105,8 @@ public class ProductIndexBaseService {
productIndexIncludeFields.add(ProductIndexEsField.deposit);
productIndexIncludeFields.add(ProductIndexEsField.depositMultiples);
productIndexIncludeFields.add(ProductIndexEsField.poolIds);
}
public List<String> getProductIndexIncludeFields() {
... ... @@ -212,6 +214,9 @@ public class ProductIndexBaseService {
productMap.put("deposit", MapUtils.getDoubleValue(map, ProductIndexEsField.deposit, 0));
productMap.put("deposit_multiples", MapUtils.getIntValue(map, ProductIndexEsField.depositMultiples));
//商品池id(活动标签需要用)
productMap.put("pool_ids", MapUtils.getString(map, ProductIndexEsField.poolIds, ""));
return productMap;
}
... ...
... ... @@ -10,6 +10,7 @@ abstract class AbstractPageSceneService extends BaseSceneService {
protected static final String RECOMMEND_PROMOTION_LIST = "recommend_promotion_list";
protected static final String CUSTOMIZE_TAG_LIST = "customize_tag";
protected static final String CUSTOMIZE_TAG_LIST_NEW = "customize_tag_new";
protected static final String STANDARD = "standard";
/**
... ...
... ... @@ -27,144 +27,145 @@ import java.util.concurrent.Executors;
@Service
public class FuzzySceneService extends AbstractPageSceneService {
private static final Logger logger = LoggerFactory.getLogger(FuzzySceneService.class);
@Autowired
private PageSelectionsService pageSelectionsService;
@Autowired
private SearchCommonHelper searchCommonHelper;
@Autowired
private RecommendWordsService recommendWordsService;
@Autowired
private SearchDynamicConfigService searchDynamicConfigService;
@Autowired
private SearchKeyWordHelper searchKeyWordService;
@Autowired
private PageAggregationHelper pageAggregationHelper;
@Autowired
private PageSelectionsBrandsService scenePageSelectionsBrandsService;
@Autowired
private ProductListSwitchService productListSwitchService;
private ExecutorService executor = Executors.newFixedThreadPool(100);
// 当少于20个商品时 返回智能搜索词提示
private static final int SMART_SUGGESTION_PRODUCT_LIMIT = 20;
@Override
public String pageId() {
return SearchPageIdDefine.PAGE_ID_SEARCH;
}
@Override
public void addParamsToParamMap(Map<String, String> paramMap) {
super.addDefaultParamsToParamMap(paramMap);
paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_GLOBAL, "Y");// 包含全球购
paramMap.put(SearchRequestParams.PARAM_SEARCH_NEED_SUGGESTION, "Y");// 返回建议词
}
/**
* @1、返回商品列表
* @2、数量太多则返回建议词
*/
@Override
public SearchApiResult productList(Map<String, String> paramMap) {
try {
// 1、参数校验
if (StringUtils.isBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_QUERY))) {
return new SearchApiResult().setCode(400).setMessage("请传query参数");
}
// 2、添加默认参数
this.addParamsToParamMap(paramMap);
// 3、获取商品列表
CompletableFuture<SearchApiResult> productListuture = CompletableFuture.supplyAsync(() -> productListSwitchService.fuzzyProductList(this.newParamMap(paramMap)), executor);
// 4、获取自定义标签聚合结果
CompletableFuture<SearchApiResult> customizeTagFuture = CompletableFuture.supplyAsync(() -> pageAggregationHelper.sceneAggCustomizeTag(this.newParamMap(paramMap)), executor);
// 5、获取促销专题
CompletableFuture<SearchApiResult> promotionsFuture = CompletableFuture.supplyAsync(() -> pageAggregationHelper.sceneAggPromotion(this.newParamMap(paramMap)),
executor);
// 6、加入建议词
SearchApiResult productListResult = productListuture.get();
this.addSuggestion(productListResult, paramMap);
// 7、模糊搜索页记录关键字对应的查询结果
String queryWord = paramMap.get("query");
if (!StringUtils.isBlank(queryWord) && !searchCommonHelper.isQuerySknOrSku(queryWord)) {
long total = ((JSONObject) productListResult.getData()).getLongValue("total");
searchKeyWordService.recordKeyWordByResultCount(queryWord, total);
}
// 8、组合结果
SearchApiResult customizeTags = customizeTagFuture.get();
SearchApiResult promotions = promotionsFuture.get();
JSONObject dataMap = (JSONObject) productListResult.getData();
dataMap.put(CUSTOMIZE_TAG_LIST, customizeTags.getData());
dataMap.put(RECOMMEND_PROMOTION_LIST, pageAggregationHelper.subRecommendPromotions(promotions.getData(),this.getPage(paramMap),1));
return productListResult;
} catch (Exception e) {
logger.error(e.getMessage(), e);
return SearchApiResultUtils.errorSearchApiResult("fuzzyProductList", paramMap, e);
}
}
@Override
public SearchApiResult aggregations(Map<String, String> paramMap) {
try {
// 0、参数校验
if (StringUtils.isBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_QUERY))) {
return new SearchApiResult().setCode(400).setMessage("请传query参数");
}
// 1、添加默认参数
this.addParamsToParamMap(paramMap);
// 2、返回聚合结果
SearchApiResult result = pageSelectionsService.aggregations(paramMap);
scenePageSelectionsBrandsService.getRecommendBrands(paramMap, result);
return result;
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new SearchApiResult().setData(null).setMessage("FuzzyAggregations Exception").setCode(500);
}
}
/**
* 获取模糊搜索的推荐词
*
* @param paramMap
* @return
*/
public void addSuggestion(SearchApiResult searchResult, Map<String, String> paramMap) {
if (searchResult == null || searchResult.getCode() != 200 || searchResult.getData() == null) {
return;
}
// 1. 判断是否需要进行term推荐
// 1.1 query不为空
String queryWord = paramMap.get(SearchRequestParams.PARAM_SEARCH_QUERY);
if (StringUtils.isEmpty(queryWord) || (queryWord.length() > 30 && !searchCommonHelper.isQuerySknOrSku(queryWord))) {
return;
}
// 1.2不是第一页直接不返回
int page = this.getPage(paramMap);
if (page != 1) {
return;
}
// 1.3请求制定需要返回term推荐
if (!"Y".equalsIgnoreCase(paramMap.get(SearchRequestParams.PARAM_SEARCH_NEED_SUGGESTION))) {
return;
}
// 1.4打开智能推荐全局开关
if (!searchDynamicConfigService.isSearchSuggestionTipsOpen()) {
return;
}
// 1.5 搜索的数量小于20条
JSONObject dataMap = ((JSONObject) searchResult.getData());
if (dataMap.getIntValue("total") >= SMART_SUGGESTION_PRODUCT_LIMIT) {
return;
}
// 1.6加入推荐词
dataMap.put("suggestion", recommendWordsService.recommendWords(searchResult, paramMap));
}
private static final Logger logger = LoggerFactory.getLogger(FuzzySceneService.class);
@Autowired
private PageSelectionsService pageSelectionsService;
@Autowired
private SearchCommonHelper searchCommonHelper;
@Autowired
private RecommendWordsService recommendWordsService;
@Autowired
private SearchDynamicConfigService searchDynamicConfigService;
@Autowired
private SearchKeyWordHelper searchKeyWordService;
@Autowired
private PageAggregationHelper pageAggregationHelper;
@Autowired
private PageSelectionsBrandsService scenePageSelectionsBrandsService;
@Autowired
private ProductListSwitchService productListSwitchService;
private ExecutorService executor = Executors.newFixedThreadPool(100);
// 当少于20个商品时 返回智能搜索词提示
private static final int SMART_SUGGESTION_PRODUCT_LIMIT = 20;
@Override
public String pageId() {
return SearchPageIdDefine.PAGE_ID_SEARCH;
}
@Override
public void addParamsToParamMap(Map<String, String> paramMap) {
super.addDefaultParamsToParamMap(paramMap);
paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_GLOBAL, "Y");// 包含全球购
paramMap.put(SearchRequestParams.PARAM_SEARCH_NEED_SUGGESTION, "Y");// 返回建议词
}
/**
* @1、返回商品列表
* @2、数量太多则返回建议词
*/
@Override
public SearchApiResult productList(Map<String, String> paramMap) {
try {
// 1、参数校验
if (StringUtils.isBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_QUERY))) {
return new SearchApiResult().setCode(400).setMessage("请传query参数");
}
// 2、添加默认参数
this.addParamsToParamMap(paramMap);
// 3、获取商品列表
CompletableFuture<SearchApiResult> productListuture = CompletableFuture.supplyAsync(() -> productListSwitchService.fuzzyProductList(this.newParamMap(paramMap)), executor);
// 4、获取自定义标签聚合结果-旧
CompletableFuture<SearchApiResult> customizeTagFuture = CompletableFuture.supplyAsync(() -> pageAggregationHelper.sceneAggCustomizeTag(this.newParamMap(paramMap)), executor);
// 4、获取自定义标签聚合结果-新
CompletableFuture<SearchApiResult> customizeTagFutureNew = CompletableFuture.supplyAsync(() -> pageAggregationHelper.sceneAggCustomizeTagNew(this.newParamMap(paramMap)), executor);
// 5、获取促销专题
CompletableFuture<SearchApiResult> promotionsFuture = CompletableFuture.supplyAsync(() -> pageAggregationHelper.sceneAggPromotion(this.newParamMap(paramMap)),
executor);
// 6、加入建议词
SearchApiResult productListResult = productListuture.get();
this.addSuggestion(productListResult, paramMap);
// 7、模糊搜索页记录关键字对应的查询结果
String queryWord = paramMap.get("query");
if (!StringUtils.isBlank(queryWord) && !searchCommonHelper.isQuerySknOrSku(queryWord)) {
long total = ((JSONObject) productListResult.getData()).getLongValue("total");
searchKeyWordService.recordKeyWordByResultCount(queryWord, total);
}
// 8、组合结果
SearchApiResult customizeTags = customizeTagFuture.get();
SearchApiResult customizeTagsNew = customizeTagFutureNew.get();
SearchApiResult promotions = promotionsFuture.get();
JSONObject dataMap = (JSONObject) productListResult.getData();
dataMap.put(CUSTOMIZE_TAG_LIST, customizeTags.getData());
dataMap.put(CUSTOMIZE_TAG_LIST_NEW, customizeTagsNew.getData());
dataMap.put(RECOMMEND_PROMOTION_LIST, pageAggregationHelper.subRecommendPromotions(promotions.getData(), this.getPage(paramMap), 1));
return productListResult;
} catch (Exception e) {
logger.error(e.getMessage(), e);
return SearchApiResultUtils.errorSearchApiResult("fuzzyProductList", paramMap, e);
}
}
@Override
public SearchApiResult aggregations(Map<String, String> paramMap) {
try {
// 0、参数校验
if (StringUtils.isBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_QUERY))) {
return new SearchApiResult().setCode(400).setMessage("请传query参数");
}
// 1、添加默认参数
this.addParamsToParamMap(paramMap);
// 2、返回聚合结果
SearchApiResult result = pageSelectionsService.aggregations(paramMap);
scenePageSelectionsBrandsService.getRecommendBrands(paramMap, result);
return result;
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new SearchApiResult().setData(null).setMessage("FuzzyAggregations Exception").setCode(500);
}
}
/**
* 获取模糊搜索的推荐词
*/
public void addSuggestion(SearchApiResult searchResult, Map<String, String> paramMap) {
if (searchResult == null || searchResult.getCode() != 200 || searchResult.getData() == null) {
return;
}
// 1. 判断是否需要进行term推荐
// 1.1 query不为空
String queryWord = paramMap.get(SearchRequestParams.PARAM_SEARCH_QUERY);
if (StringUtils.isEmpty(queryWord) || (queryWord.length() > 30 && !searchCommonHelper.isQuerySknOrSku(queryWord))) {
return;
}
// 1.2不是第一页直接不返回
int page = this.getPage(paramMap);
if (page != 1) {
return;
}
// 1.3请求制定需要返回term推荐
if (!"Y".equalsIgnoreCase(paramMap.get(SearchRequestParams.PARAM_SEARCH_NEED_SUGGESTION))) {
return;
}
// 1.4打开智能推荐全局开关
if (!searchDynamicConfigService.isSearchSuggestionTipsOpen()) {
return;
}
// 1.5 搜索的数量小于20条
JSONObject dataMap = ((JSONObject) searchResult.getData());
if (dataMap.getIntValue("total") >= SMART_SUGGESTION_PRODUCT_LIMIT) {
return;
}
// 1.6加入推荐词
dataMap.put("suggestion", recommendWordsService.recommendWords(searchResult, paramMap));
}
}
... ...
... ... @@ -82,16 +82,20 @@ public class SortPageSceneService extends AbstractPageSceneService {
executorService);
CompletableFuture<SearchApiResult> customizeTagFuture = CompletableFuture.supplyAsync(() -> pageAggregationHelper.sceneAggCustomizeTag(this.newParamMap(paramMap)),
executorService);
CompletableFuture<SearchApiResult> customizeTagFutureNew = CompletableFuture.supplyAsync(() -> pageAggregationHelper.sceneAggCustomizeTagNew(this.newParamMap(paramMap)),
executorService);
CompletableFuture<SearchApiResult> promotionsFuture = CompletableFuture.supplyAsync(() -> pageAggregationHelper.sceneAggPromotion(this.newParamMap(paramMap)),
executorService);
// 3、组合结果
SearchApiResult productList = productListFuture.get();
SearchApiResult standards = standardsFuture.get();
SearchApiResult customizeTags = customizeTagFuture.get();
SearchApiResult customizeTagsNew = customizeTagFutureNew.get();
SearchApiResult promotions = promotionsFuture.get();
JSONObject jsonObject = (JSONObject) productList.getData();
jsonObject.put(STANDARD, standards.getData());
jsonObject.put(CUSTOMIZE_TAG_LIST, customizeTags.getData());
jsonObject.put(CUSTOMIZE_TAG_LIST_NEW, customizeTagsNew.getData());
jsonObject.put(RECOMMEND_PROMOTION_LIST, pageAggregationHelper.subRecommendPromotions(promotions.getData(), this.getPage(paramMap), 1));
return productList;
} catch (Exception e) {
... ...
... ... @@ -48,7 +48,7 @@ public class PageAggregationHelper {
/**
* 聚合规则-非个性化
*
*
* @param paramMap
* @return
*/
... ... @@ -65,15 +65,15 @@ public class PageAggregationHelper {
}
/**
* 聚合自定义标签-非个性化
*
* 聚合自定义标签-非个性化-老的
*
* @param paramMap
* @return
*/
@SearchCacheAble(cacheName = "SCENE_AGG_CUSTOMIZETAG", cacheInMinute = 15, excludeParams = { "uid","udid","order", "page", "viewNum", "yh_channel" })
public SearchApiResult sceneAggCustomizeTag(Map<String, String> paramMap) {
try {
IAggregation customizeAggregation = aggregationFactory.getCustomizeTagAggregation(paramMap);
IAggregation customizeAggregation = aggregationFactory.getActivityTagAggregation(paramMap);
Object respone = this.getAggregationResponse(customizeAggregation, paramMap);
return new SearchApiResult().setData(respone);
} catch (Exception e) {
... ... @@ -82,9 +82,27 @@ public class PageAggregationHelper {
}
}
/**
* 聚合自定义标签-非个性化-新的
*
* @param paramMap
* @return
*/
@SearchCacheAble(cacheName = "SCENE_AGG_CUSTOMIZETAG_NEW", cacheInMinute = 15, excludeParams = { "uid","udid","order", "page", "viewNum", "yh_channel" })
public SearchApiResult sceneAggCustomizeTagNew(Map<String, String> paramMap) {
try {
IAggregation customizeAggregation = aggregationFactory.getCustomizeTagAggregation(paramMap);
Object respone = this.getAggregationResponse(customizeAggregation, paramMap);
return new SearchApiResult().setData(respone);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new SearchApiResult().setCode(500).setMessage("secneAggCustomizeTag Exception");
}
}
/**
* 聚合促销专题-非个性化
*
*
* @param paramMap
* @return
*/
... ... @@ -129,7 +147,7 @@ public class PageAggregationHelper {
/**
* 从缓存中获取数据后按分页参数截取
*
*
* @param recommendPromotions
* @param page
* @param count
... ...