Authored by Zhao

Merge branch 'zj' into 6.1

package com.yoho.search.models;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
public class RecommendPromotionAggVO {
@JSONField(name = "promotion_info_id")
private int promotionInfoId;
@JSONField(name = "coverimg_url")
private String coverImgUrl;
private String title;
public int getPromotionInfoId() {
return promotionInfoId;
}
public void setPromotionInfoId(int promotionInfoId) {
this.promotionInfoId = promotionInfoId;
}
public String getCoverImgUrl() {
return coverImgUrl;
}
public void setCoverImgUrl(String coverImgUrl) {
this.coverImgUrl = coverImgUrl;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public static void main(String[] args) {
RecommendPromotionAggVO recommendPromotionAggVO = new RecommendPromotionAggVO();
recommendPromotionAggVO.setPromotionInfoId(1);
recommendPromotionAggVO.setCoverImgUrl("sdf");
recommendPromotionAggVO.setTitle("dfas");
System.out.println(JSON.toJSONString(recommendPromotionAggVO));
;
}
}
... ...
... ... @@ -4,6 +4,7 @@ import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.yoho.search.service.service.IAggRecommendService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
... ... @@ -24,6 +25,9 @@ public class FuzzySceneController {
@Autowired
private FuzzySceneService fuzzySearchService;
@Autowired
private IAggRecommendService aggRecommendService;
/**
* 模糊搜索列表
... ... @@ -34,7 +38,9 @@ public class FuzzySceneController {
@ResponseBody
public SearchApiResult fuzzyProductList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return fuzzySearchService.productList(paramMap);
SearchApiResult searchApiResult = fuzzySearchService.productList(paramMap);
aggRecommendService.recommendPromotion(searchApiResult, paramMap);
return searchApiResult;
}
/**
... ...
... ... @@ -4,6 +4,7 @@ import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.yoho.search.service.service.IAggRecommendService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
... ... @@ -24,6 +25,8 @@ public class SortSceneController {
@Autowired
private SortSceneService sortSearchService;
@Autowired
private IAggRecommendService aggRecommendService;
/**
* 品类页列表
... ... @@ -34,7 +37,9 @@ public class SortSceneController {
@ResponseBody
public SearchApiResult sortProductList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return sortSearchService.productList(paramMap);
SearchApiResult searchApiResult = sortSearchService.productList(paramMap);
aggRecommendService.recommendPromotion(searchApiResult, paramMap);
return searchApiResult;
}
/**
... ...
... ... @@ -95,6 +95,10 @@ public class AggregationFactoryService {
return new StandardAggregation(standardIndexBaseService, paramMap);
}
public IAggregation getRecommendPromotionAggregation(int promotionCount) {
return new RecommendPromotionAggregation(promotionIndexBaseService, promotionCount);
}
public IAggregation getRecentShelveDayAggregation() {
return new RecentShelveDayAggregation();
}
... ...
package com.yoho.search.service.aggregations.impls;
import com.yoho.search.base.utils.DateUtil;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.core.es.agg.AbstractAggregation;
import com.yoho.search.service.base.index.PromotionIndexBaseService;
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.*;
import java.util.stream.Collectors;
public class RecommendPromotionAggregation extends AbstractAggregation {
private static String NESTED_PATH = "matchedPromotions";
private PromotionIndexBaseService promotionIndexBaseService;
private int promotionCount;
RecommendPromotionAggregation(PromotionIndexBaseService promotionIndexBaseService, int promotionCount) {
this.promotionIndexBaseService = promotionIndexBaseService;
this.promotionCount = promotionCount;
}
public int getPromotionCount() {
return promotionCount;
}
public void setPromotionCount(int promotionCount) {
this.promotionCount = promotionCount;
}
@Override
public String aggName() {
return "recommendPromotionAgg";
}
@Override
public String filterName() {
return "cxfilter";
}
@Override
public AbstractAggregationBuilder<?> getBuilder() {
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
Date now = new Date();
boolFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.MATCHED_PROMOTIONS_ENDTIME).gt(DateUtil.setHourSeonds(now, 1, 0, 0)));
boolFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.MATCHED_PROMOTIONS_STARTTIME).lt(DateUtil.setHourSeonds(now, 0, 0, 0)));
AbstractAggregationBuilder<NestedAggregationBuilder> nestedAggregationBuilder =
AggregationBuilders.nested(aggName(), NESTED_PATH)
.subAggregation(AggregationBuilders.filter("cxfilter", boolFilter)
.subAggregation(AggregationBuilders.terms("promotionIdAgg").field(ProductIndexEsField.MATCHED_PROMOTIONS_ID).size(getPromotionCount()).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())) {
InternalFilter filter = (InternalFilter)aggregation.getAggregations().asList().get(0);
List<LongTerms.Bucket> longTerms = ((LongTerms)filter.getAggregations().asList().get(0)).getBucketsInternal();
List<Integer> ids = longTerms.stream().map(e -> e.getKeyAsNumber().intValue()).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(ids)) {
return promotionIndexBaseService.getPromotionInfosByIds(ISearchConstants.INDEX_NAME_PROMOTIONINDEX, ids);
}
}
return null;
}
}
... ...
package com.yoho.search.service.base.index;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.models.RecommendPromotionAggVO;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
... ... @@ -19,6 +20,7 @@ import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.service.base.SearchCommonService;
import org.springframework.util.CollectionUtils;
/**
* Created by wangnan on 2017/5/11.
... ... @@ -51,6 +53,27 @@ public class PromotionIndexBaseService {
}
}
public List<RecommendPromotionAggVO> getPromotionInfosByIds(String indexName, List<Integer> ids){
SearchParam searchParam = new SearchParam();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termsQuery(ProductIndexEsField.id, ids));
boolQueryBuilder.must(QueryBuilders.termQuery(ProductIndexEsField.status, 1));
searchParam.setFiter(boolQueryBuilder);
searchParam.setSize(ids.size());
SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
if (searchResult == null || CollectionUtils.isEmpty(searchResult.getResultList())) {
return Collections.emptyList();
}
List<RecommendPromotionAggVO> resultList = new ArrayList<>();
for (Map<String, Object> esMap : searchResult.getResultList()) {
if (!CollectionUtils.isEmpty(esMap)) {
resultList.add(parsePromotionInfos(esMap));
}
}
return resultList;
}
private List<Map<String, Object>> queryListByParam(SearchParam searchParam) {
List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
SearchResult searchResult = searchCommonService.doSearch(INDEX_NAME, searchParam);
... ... @@ -71,8 +94,8 @@ public class PromotionIndexBaseService {
}
return boolFilter;
}
public Map<String, Object> getMap(Map<String, Object> esMap) {
private Map<String, Object> getMap(Map<String, Object> esMap) {
Map<String, Object> map = new HashMap<>();
int id = MapUtils.getIntValue(esMap, "id", 0);
map.put("is_promotion", id + "");
... ... @@ -80,4 +103,12 @@ public class PromotionIndexBaseService {
return map;
}
private RecommendPromotionAggVO parsePromotionInfos(Map<String, Object> esMap) {
RecommendPromotionAggVO recommendPromotionAggVO = new RecommendPromotionAggVO();
recommendPromotionAggVO.setPromotionInfoId(MapUtils.getIntValue(esMap, "id", 0));
recommendPromotionAggVO.setTitle(MapUtils.getString(esMap,"title", ""));
recommendPromotionAggVO.setCoverImgUrl(MapUtils.getString(esMap, "commonBanner", ""));
return recommendPromotionAggVO;
}
}
... ...
... ... @@ -14,7 +14,7 @@ public interface IAggRecommendService {
* @param paramMap
* @return
*/
public SearchApiResult aggRecommendBrand(Map<String, String> paramMap);
SearchApiResult aggRecommendBrand(Map<String, String> paramMap);
/**
* 获取品牌的聚合结果[使用本地缓存]
... ... @@ -22,7 +22,7 @@ public interface IAggRecommendService {
* @param paramMap
* @return
*/
public SearchApiResult aggRecommendBrand(Map<String, String> paramMap, BoolQueryBuilder mustFilter);
SearchApiResult aggRecommendBrand(Map<String, String> paramMap, BoolQueryBuilder mustFilter);
/**
... ... @@ -31,6 +31,14 @@ public interface IAggRecommendService {
* @param paramMap
* @return
*/
public SearchApiResult aggRecommendShop(Map<String, String> paramMap);
SearchApiResult aggRecommendShop(Map<String, String> paramMap);
/**
* 获取促销的聚合结果[使用本地缓存]
*
* @param paramMap
* @return
*/
void recommendPromotion(SearchApiResult searchApiResult, Map<String, String> paramMap);
}
... ...
package com.yoho.search.service.service.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import javax.annotation.PostConstruct;
import com.yoho.search.base.utils.DateUtil;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
... ... @@ -36,6 +34,8 @@ import com.yoho.search.service.service.IAggRecommendService;
public class AggRecommendServiceImpl implements IAggRecommendService {
private static final Logger logger = LoggerFactory.getLogger(AggRecommendServiceImpl.class);
private static final String RECOMMENG_PROMOTION_LIST = "recommend_promotion_list";
private static final int DEFAULT_AGGREGATION_COUNT = 100;
@Autowired
private AggregationService aggregationService;
... ... @@ -132,7 +132,7 @@ public class AggRecommendServiceImpl implements IAggRecommendService {
searchParam.setAggregationBuilders(Arrays.asList(recommendShopAgg.getBuilder()));
// 4、构建offset
searchParam.setOffset(100);// justForCache
searchParam.setOffset(DEFAULT_AGGREGATION_COUNT);// justForCache
// 5、从缓存中获取
final String productIndexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
... ... @@ -158,6 +158,69 @@ public class AggRecommendServiceImpl implements IAggRecommendService {
}
}
@Override
public void recommendPromotion(SearchApiResult searchResult, Map<String, String> paramMap) {
try {
if (searchResult == null || searchResult.getCode() != 200 || searchResult.getData() == null) {
return;
}
JSONObject dataMap = ((JSONObject) searchResult.getData());
// 1、获取核心参数
int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
int count = 2;
// 1.1添加默认参数
paramMap.remove(SearchRequestParams.PARAM_SEARCH_ORDER);// 此接口不支持order
paramMap.put(SearchRequestParams.PARAM_SEARCH_GLOBAL_FILTER_BRAND, "Y");// 页面屏蔽
paramMap.put(SearchRequestParams.PARAM_SEARCH_STATUS, "1");// 上架
paramMap.put(SearchRequestParams.PARAM_SEARCH_STOCKNUM, "1");// 有库存
paramMap.put(SearchRequestParams.PARAM_SEARCH_ISOUTLETS, "2");// 非奥莱
paramMap.put(SearchRequestParams.PARAM_SEARCH_ATTRIBUTE_NOT, "2");// 非赠品
// 2、构建带queryBuilder和filter的SearchParam
SearchParam searchParam = searchParamHelper.buildWithPersional(paramMap, false);
// 3、构造聚合操作
IAggregation recommendPromotionAgg = aggregationFactoryService.getRecommendPromotionAggregation(DEFAULT_AGGREGATION_COUNT);
searchParam.setAggregationBuilders(Arrays.asList(recommendPromotionAgg.getBuilder()));
// 4、构建offset
searchParam.setOffset(DEFAULT_AGGREGATION_COUNT);// justForCache
// 5、从缓存中获取
JSONArray cacheJSONArray = searchCacheService.getJSONArrayFromCache(searchCache, ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
if (cacheJSONArray != null) {
SearchCacheMatchLogger.doSearchCacheMatchLog("/productList.json", paramMap);
dataMap.put(RECOMMENG_PROMOTION_LIST, subList(cacheJSONArray, page, count));
return;
}
// 6、从ES中获取
JSONObject recommendPromotionResult = aggregationService.getAggNameAndResponse(recommendPromotionAgg, searchParam);
if (recommendPromotionResult == null) {
return;
}
// 7、生成结果并且加入缓存
JSONArray recommendPromotions = recommendPromotionResult.getJSONArray(recommendPromotionAgg.aggName());
if (recommendPromotions != null) {
searchCacheService.addJSONArrayToCache(searchCache, ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam, recommendPromotions);
dataMap.put(RECOMMENG_PROMOTION_LIST, subList(recommendPromotions, page, count));
}
} catch (Exception e) {
return;
}
return;
}
private List<Object> subList(JSONArray sourceList, int page, int count) {
if (sourceList != null && !sourceList.isEmpty()) {
int start = (page - 1) * count;
int end = start + count;
if (start >= sourceList.size()) {
return Collections.emptyList();
}
if (end > sourceList.size()) {
end = sourceList.size();
}
return sourceList.subList(start, end);
}
return Collections.emptyList();
}
private SearchApiResult getRecommendShopSearchApiResult(JSONArray cacheJSONArray, int page, int count) {
List<Map<String, Object>> cacheList = new ArrayList<Map<String, Object>>();
for (int i = 0; i < cacheJSONArray.size(); i++) {
... ... @@ -166,5 +229,5 @@ public class AggRecommendServiceImpl implements IAggRecommendService {
List<Map<String, Object>> results = CollectionUtils.memoryPaging(cacheList, page, count);
return new SearchApiResult().setData(results);
}
}
... ...