Authored by wangnan

Merge branch 'wn_promotion' of http://git.yoho.cn/yoho-search/yoho-search-service into wn_promotion

Showing 24 changed files with 982 additions and 114 deletions
  1 +package com.yoho.search.recall.scene.beans.cache;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.alibaba.fastjson.TypeReference;
  6 +import com.yoho.search.base.utils.ISearchConstants;
  7 +import com.yoho.search.base.utils.ProductIndexEsField;
  8 +import com.yoho.search.core.es.model.SearchParam;
  9 +import com.yoho.search.core.es.model.SearchResult;
  10 +import com.yoho.search.recall.scene.beans.helper.SknImgHelper;
  11 +import com.yoho.search.recall.scene.models.req.*;
  12 +import com.yoho.search.service.base.SearchCommonService;
  13 +import com.yoho.search.service.base.index.BrandIndexBaseService;
  14 +import com.yoho.search.service.base.index.ProductIndexBaseService;
  15 +import org.apache.commons.collections.MapUtils;
  16 +import org.springframework.beans.factory.annotation.Autowired;
  17 +import org.springframework.stereotype.Component;
  18 +import org.springframework.util.CollectionUtils;
  19 +
  20 +import java.util.*;
  21 +import java.util.stream.Collectors;
  22 +
  23 +@Component
  24 +public class ShopProductCacheBean extends AbstractCacheBean<ShopProductRequest, ShopProductResponse, ShopProductRequestResponse> {
  25 +
  26 + @Autowired
  27 + private SearchCommonService searchCommonService;
  28 + @Autowired
  29 + private SknImgHelper sknImgHelper;
  30 + @Autowired
  31 + private ProductIndexBaseService productIndexBaseService;
  32 + @Autowired
  33 + private BrandIndexBaseService brandIndexBaseService;
  34 +
  35 + public List<ShopProductResponse> getShopSknByShopId(List<ShopProductRequest> shopSknRequests, String hrShopIds) {
  36 + List<ShopProductRequestResponse> shopSknRequestResponses = new ArrayList<>();
  37 + for (ShopProductRequest request : shopSknRequests) {
  38 + shopSknRequestResponses.add(new ShopProductRequestResponse(request));
  39 + }
  40 + //2、执行父类方法
  41 + this.bacthFillResponseWithCache(shopSknRequestResponses, shopSknRequestResponses.size());
  42 + List<ShopProductResponse> shopProductResponses = shopSknRequestResponses.stream().map(ShopProductRequestResponse::getResponse).filter(Objects::nonNull).collect(Collectors.toList());
  43 + for (ShopProductResponse response : shopProductResponses) {
  44 + response.setHr_shop_id(hrShopIds);
  45 + }
  46 + //3、返回结果
  47 + return shopProductResponses;
  48 + }
  49 +
  50 + @Override
  51 + protected boolean useEhCache() {
  52 + return false;
  53 + }
  54 +
  55 + @Override
  56 + protected Map<ShopProductRequest, ShopProductResponse> queryMissCacheRequestResults(List<ShopProductRequestResponse> missCacheRequests) {
  57 + Map<ShopProductRequest, ShopProductResponse> results = new HashMap<>();
  58 + if (missCacheRequests == null || missCacheRequests.isEmpty()) {
  59 + return results;
  60 + }
  61 + List<SearchParam> searchParams = new ArrayList<>();
  62 + for (ShopProductRequestResponse requestResponse : missCacheRequests) {
  63 + searchParams.add(requestResponse.getRequest().searchParam());
  64 + }
  65 + //2、执行搜索
  66 + List<SearchResult> searchResults = searchCommonService.doMutiSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParams);
  67 + Set<Integer> brandIds = new HashSet<>();
  68 + for (SearchResult searchResult : searchResults) {
  69 + List<Map<String, Object>> resultList = searchResult.getResultList();
  70 + brandIds.addAll(resultList.stream().map(result -> MapUtils.getInteger(result, ProductIndexEsField.brandId, 0)).collect(Collectors.toSet()));
  71 + }
  72 + Map<String, Map<String, Object>> brandMap = new HashMap<>();
  73 + if (!CollectionUtils.isEmpty(brandIds)) {
  74 + brandMap = brandIndexBaseService.getBrandMapByIds(brandIds);
  75 + }
  76 + //获得变价计划
  77 + Map<String, List<Map<String, Object>>> shopProductListMap = new HashMap<>();
  78 + for (int i = 0; i < missCacheRequests.size(); i++) {
  79 + ShopProductRequest request = missCacheRequests.get(i).getRequest();
  80 + SearchResult searchResult = searchResults.get(i);
  81 + if (request != null && searchResult != null) {
  82 + shopProductListMap.put(request.getShopId().toString(), searchResult.getResultList());
  83 + }
  84 + }
  85 + shopProductListMap = productIndexBaseService.getProductListWithPricePlan(shopProductListMap);
  86 + for (int i = 0; i < missCacheRequests.size(); i++) {
  87 + ShopProductRequest request = missCacheRequests.get(i).getRequest();
  88 + List<Map<String, Object>> productList = shopProductListMap.get(request.getShopId().toString());
  89 + ShopProductResponse response = buildResponse(productList, brandMap, request);
  90 + results.put(request, response);
  91 + }
  92 + return results;
  93 + }
  94 +
  95 + private ShopProductResponse buildResponse(List<Map<String, Object>> productList, Map<String, Map<String, Object>> brandMap, ShopProductRequest request) {
  96 + ShopProductResponse response = new ShopProductResponse();
  97 + List<ShopProductResponse.ShopProduct> shopProductList = new ArrayList<>();
  98 + response.setShop_id(request.getShopId());
  99 + response.setShop_product_list(shopProductList);
  100 +
  101 + if (!CollectionUtils.isEmpty(productList)) {
  102 + Map<String, Object> product = productList.get(0);
  103 + response.setShop_name(MapUtils.getString(product, "shop_name", ""));
  104 + //1、构建结果
  105 + for (Map<String, Object> productInfo : productList) {
  106 + ShopProductResponse.ShopProduct shopProduct = new ShopProductResponse.ShopProduct();
  107 + shopProduct.setProduct_skn(MapUtils.getInteger(productInfo, "product_skn", 0));
  108 + shopProduct.setProduct_name(MapUtils.getString(productInfo, "product_name", ""));
  109 + shopProduct.setGender(MapUtils.getString(productInfo, "gender", "1,3"));
  110 + shopProduct.setSales_price(MapUtils.getDouble(productInfo, "sales_price", 0.0));
  111 + shopProduct.setDefault_images(MapUtils.getString(productInfo, "default_images", ""));
  112 + String brandId = MapUtils.getString(productInfo, "brand_id", "");
  113 + Map<String, Object> brand = brandMap.get(brandId);
  114 + if (brand != null) {
  115 + shopProduct.setBrand_name(MapUtils.getString(brand, "brand_name", ""));
  116 + shopProduct.setBrand_ico(MapUtils.getString(brand, "brand_ico", ""));
  117 + }
  118 + shopProduct.setProduct_price_plan_list(MapUtils.getObject(productInfo, "product_price_plan_list", Collections.emptyList()));
  119 + List<JSONObject> goodsList = JSON.parseObject(JSON.toJSONString(productInfo.get("goods_list")), new TypeReference<List<JSONObject>>() {});
  120 + sknImgHelper.genImage(goodsList, shopProduct);
  121 + shopProductList.add(shopProduct);
  122 + }
  123 + }
  124 + return response;
  125 + }
  126 +
  127 +}
  1 +package com.yoho.search.recall.scene.beans.cache;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.alibaba.fastjson.TypeReference;
  6 +import com.yoho.search.base.utils.ISearchConstants;
  7 +import com.yoho.search.base.utils.ProductIndexEsField;
  8 +import com.yoho.search.core.es.model.SearchParam;
  9 +import com.yoho.search.core.es.model.SearchResult;
  10 +import com.yoho.search.recall.scene.beans.helper.SknImgHelper;
  11 +import com.yoho.search.recall.scene.models.req.SknImgsRequestResponse;
  12 +import com.yoho.search.recall.scene.models.req.SknImgsResponse;
  13 +import com.yoho.search.recall.scene.models.req.SknImgsResquest;
  14 +import com.yoho.search.service.base.SearchCommonService;
  15 +import org.apache.commons.collections.CollectionUtils;
  16 +import org.apache.commons.collections.MapUtils;
  17 +import org.elasticsearch.index.query.QueryBuilders;
  18 +import org.springframework.beans.factory.annotation.Autowired;
  19 +import org.springframework.stereotype.Component;
  20 +
  21 +import java.util.*;
  22 +
  23 +@Component
  24 +public class SknImgsCacheBean extends AbstractCacheBean<SknImgsResquest, SknImgsResponse, SknImgsRequestResponse> {
  25 +
  26 + @Autowired
  27 + private SearchCommonService searchCommonService;
  28 + @Autowired
  29 + private SknImgHelper sknImgHelper;
  30 +
  31 + @Override
  32 + protected boolean useEhCache() {
  33 + return false;
  34 + }
  35 +
  36 + public Map<String, SknImgsResponse> querySknImgs(List<String> productSkns) {
  37 + //1、构建请求与返回结果
  38 + final List<SknImgsRequestResponse> requestResponses = new ArrayList<>();
  39 + for (String productSkn : productSkns) {
  40 + requestResponses.add(new SknImgsRequestResponse(new SknImgsResquest(Integer.valueOf(productSkn))));
  41 + }
  42 + //2、调父类方法
  43 + this.bacthFillResponseWithCache(requestResponses, productSkns.size());
  44 + //2、构造返回结果
  45 + Map<String, SknImgsResponse> finalResults = new HashMap<>();
  46 + for (SknImgsRequestResponse sknImgsRequestResponse : requestResponses) {
  47 + if (sknImgsRequestResponse != null && sknImgsRequestResponse.getResponse() != null) {
  48 + finalResults.put(sknImgsRequestResponse.getRequest().getProductSkn().toString(), sknImgsRequestResponse.getResponse());
  49 + }
  50 + }
  51 + return finalResults;
  52 + }
  53 +
  54 + @Override
  55 + protected Map<SknImgsResquest, SknImgsResponse> queryMissCacheRequestResults(List<SknImgsRequestResponse> missCacheRequests) {
  56 + //1、合法性判断
  57 + Map<SknImgsResquest, SknImgsResponse> results = new HashMap<>();
  58 + if (missCacheRequests == null || missCacheRequests.isEmpty()) {
  59 + return results;
  60 + }
  61 + //2、获取skn
  62 + List<Integer> productSkns = new ArrayList<>();
  63 + for (SknImgsRequestResponse sknDefaultImgRequestResponse : missCacheRequests) {
  64 + productSkns.add(sknDefaultImgRequestResponse.getRequest().getProductSkn());
  65 + }
  66 + //3、构建SearchParam
  67 + SearchParam searchParam = new SearchParam();
  68 + searchParam.setSize(productSkns.size());
  69 + searchParam.setFiter(QueryBuilders.termsQuery(ProductIndexEsField.productSkn, productSkns));
  70 + searchParam.setIncludeFields(missCacheRequests.get(0).getRequest().includeFields());
  71 + SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
  72 +
  73 + if (searchResult != null && CollectionUtils.isNotEmpty(searchResult.getResultList())) {
  74 + Map<String, SknImgsResponse> defaultImgTempMap = new HashMap<>();
  75 + for (Map<String, Object> product : searchResult.getResultList()) {
  76 + SknImgsResponse response = new SknImgsResponse();
  77 + response.setDefault_images(MapUtils.getString(product, ProductIndexEsField.defaultImages, ""));
  78 + response.setSkn_default_img(MapUtils.getString(product, ProductIndexEsField.sknDefaultImg, ""));
  79 + response.setGender(MapUtils.getString(product, ProductIndexEsField.gender, ""));
  80 + List<JSONObject> goodsList = JSON.parseObject(JSON.toJSONString(product.get(ProductIndexEsField.goodsList)), new TypeReference<List<JSONObject>>() {});
  81 + sknImgHelper.genImage(goodsList, response);
  82 + defaultImgTempMap.put(MapUtils.getString(product,ProductIndexEsField.productSkn,""), response);
  83 + }
  84 + for (SknImgsRequestResponse requestResponse : missCacheRequests) {
  85 + results.put(requestResponse.getRequest(), defaultImgTempMap.get(requestResponse.getRequest().getProductSkn().toString()));
  86 + }
  87 + }
  88 + return results;
  89 + }
  90 +}
  1 +package com.yoho.search.recall.scene.beans.helper;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import org.apache.commons.lang3.StringUtils;
  5 +import org.springframework.stereotype.Component;
  6 +import org.springframework.util.CollectionUtils;
  7 +
  8 +import java.lang.reflect.Method;
  9 +import java.util.List;
  10 +
  11 +@Component
  12 +public class SknImgHelper<Response> {
  13 +
  14 + public void genImage(List<JSONObject> goodsList, Response response) {
  15 + if(CollectionUtils.isEmpty(goodsList)){
  16 + return;
  17 + }
  18 + JSONObject firstGood = null;
  19 + for (JSONObject good : goodsList) {
  20 + if ("Y".equals(good.getString("is_default")) && StringUtils.isNotEmpty(good.getString("images_url"))) {
  21 + genImage(good, response);
  22 + return;
  23 + }
  24 + // 有可能,goodlist中的所有good都没有cover1或者cover2,最终就采用第一个good
  25 + if(null == firstGood && StringUtils.isNotEmpty(good.getString("images_url"))){
  26 + firstGood = good;
  27 + }
  28 + }
  29 + if (firstGood != null) {
  30 + genImage(firstGood, response);
  31 + }
  32 + }
  33 +
  34 + private void genImage(JSONObject good, Response response) {
  35 + String images_url = good.getString("images_url");
  36 + String conver_1 = good.getString("cover_1");
  37 + String conver_2 = good.getString("cover_2");
  38 + try {
  39 + Method[] methods = response.getClass().getDeclaredMethods();
  40 + // 循环查找想要的方法
  41 + for(Method method : methods) {
  42 + if("setCover_1".equals(method.getName())) {
  43 + method.invoke(response, (StringUtils.isEmpty(conver_1) ? images_url : conver_1));
  44 + }
  45 + if("setCover_2".equals(method.getName())) {
  46 + method.invoke(response, (StringUtils.isEmpty(conver_2) ? images_url : conver_2));
  47 + }
  48 + }
  49 +
  50 + } catch (Exception e) {
  51 + }
  52 + }
  53 +
  54 +
  55 +
  56 +}
@@ -30,4 +30,8 @@ public class CacheTimeConstants { @@ -30,4 +30,8 @@ public class CacheTimeConstants {
30 //页面个性化因子的缓存 30 //页面个性化因子的缓存
31 public static final int PAGE_PERSIONAL_FACTOR = 60 ; 31 public static final int PAGE_PERSIONAL_FACTOR = 60 ;
32 32
  33 + public static final int CACHE_60_MINUTE = 60 ;
  34 +
  35 + public static final int CACHE_10_MINUTE = 10 ;
  36 +
33 } 37 }
  1 +package com.yoho.search.recall.scene.models.req;
  2 +
  3 +import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
  4 +import com.yoho.search.base.utils.MD5Util;
  5 +import com.yoho.search.base.utils.ProductIndexEsField;
  6 +import com.yoho.search.core.es.model.SearchParam;
  7 +import com.yoho.search.recall.scene.constants.CacheTimeConstants;
  8 +import com.yoho.search.recall.scene.models.common.ICacheRequest;
  9 +import com.yoho.search.recall.scene.models.common.ParamQueryFilter;
  10 +import org.elasticsearch.index.query.BoolQueryBuilder;
  11 +import org.elasticsearch.index.query.QueryBuilders;
  12 +import org.elasticsearch.search.sort.SortBuilders;
  13 +import org.elasticsearch.search.sort.SortOrder;
  14 +
  15 +import java.util.Arrays;
  16 +import java.util.List;
  17 +
  18 +public class ShopProductRequest implements ICacheRequest {
  19 + private static final List<String> includeFields = Arrays.asList(ProductIndexEsField.productSkn, ProductIndexEsField.productName, ProductIndexEsField.shopId, ProductIndexEsField.shopName, ProductIndexEsField.defaultImages, ProductIndexEsField.goodsList, ProductIndexEsField.salesPrice,ProductIndexEsField.gender, ProductIndexEsField.brandId);
  20 + private ParamQueryFilter paramQueryFilter;
  21 + private Integer shopId;
  22 + private RedisKeyBuilder redisKeyBuilder;
  23 +
  24 + public ShopProductRequest(ParamQueryFilter paramQueryFilter, Integer shopId) {
  25 + this.paramQueryFilter = paramQueryFilter;
  26 + this.shopId = shopId;
  27 + this.redisKeyBuilder = genRedisKeyBuilder();
  28 + }
  29 +
  30 + public RedisKeyBuilder genRedisKeyBuilder() {
  31 + StringBuilder stringBuilder = new StringBuilder();
  32 + stringBuilder.append(paramQueryFilter == null ? "" : paramQueryFilter.getParamMd5Key());
  33 + stringBuilder.append(shopId);
  34 + String value = MD5Util.string2MD5(stringBuilder.toString());
  35 + return RedisKeyBuilder.newInstance().appendFixed("YOHOSEARCH:").appendFixed("SHOP_SKN:").appendVar(cacheTimeInMinute()).appendFixed(":").appendVar(value);
  36 + }
  37 +
  38 + @Override
  39 + public RedisKeyBuilder redisKeyBuilder() {
  40 + return redisKeyBuilder;
  41 + }
  42 +
  43 + @Override
  44 + public int cacheTimeInMinute() {
  45 + return CacheTimeConstants.CACHE_10_MINUTE;
  46 + }
  47 +
  48 + public ParamQueryFilter getParamQueryFilter() {
  49 + return paramQueryFilter;
  50 + }
  51 +
  52 + public Integer getShopId() {
  53 + return shopId;
  54 + }
  55 +
  56 + public void setShopId(Integer shopId) {
  57 + this.shopId = shopId;
  58 + }
  59 +
  60 + public SearchParam searchParam() {
  61 + SearchParam searchParam = new SearchParam();
  62 + if (paramQueryFilter != null && paramQueryFilter.getParamQuery() != null) {
  63 + searchParam.setQuery(paramQueryFilter.getParamQuery());
  64 + }
  65 + BoolQueryBuilder realFilter = QueryBuilders.boolQuery();
  66 + realFilter.must(QueryBuilders.termQuery(ProductIndexEsField.shopId, shopId));
  67 + if (paramQueryFilter != null && paramQueryFilter.getParamFilter() != null) {
  68 + realFilter.must(paramQueryFilter.getParamFilter());
  69 + }
  70 + searchParam.setFiter(realFilter);
  71 + searchParam.setIncludeFields(includeFields);
  72 + searchParam.setSortBuilders(Arrays.asList(SortBuilders.fieldSort(ProductIndexEsField.heatValue).order(SortOrder.DESC), SortBuilders.fieldSort(ProductIndexEsField.shelveTime).order(SortOrder.DESC)));
  73 + searchParam.setOffset(0);
  74 + searchParam.setSize(10);
  75 + return searchParam;
  76 + }
  77 +}
  1 +package com.yoho.search.recall.scene.models.req;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.yoho.search.base.utils.Transfer;
  5 +import com.yoho.search.recall.scene.models.common.AbstractCacheRequestResponse;
  6 +
  7 +public class ShopProductRequestResponse extends AbstractCacheRequestResponse<ShopProductRequest, ShopProductResponse> {
  8 +
  9 + public ShopProductRequestResponse(ShopProductRequest request) {
  10 + super(request);
  11 + }
  12 +
  13 + @Override
  14 + public Transfer<String, ShopProductResponse> getToResponseTransfer() {
  15 + return (v) -> JSON.parseObject(v, ShopProductResponse.class);
  16 + }
  17 +
  18 + @Override
  19 + public Transfer<ShopProductResponse, String> getFromResponseTransfer() {
  20 + return (v) -> JSON.toJSONString(v);
  21 + }
  22 +}
  1 +package com.yoho.search.recall.scene.models.req;
  2 +
  3 +import java.util.List;
  4 +
  5 +public class ShopProductResponse {
  6 + private String hr_shop_id;
  7 + private Integer shop_id;
  8 + private String shop_name;
  9 + private List<ShopProduct> shop_product_list;
  10 +
  11 + public static class ShopProduct {
  12 + private Integer product_skn;
  13 + private String product_name;
  14 + private String gender;
  15 + private String default_images;
  16 + private String cover_1;
  17 + private String cover_2;
  18 + private Double sales_price;
  19 + private Object product_price_plan_list;
  20 + private String brand_name;
  21 + private String brand_ico;
  22 +
  23 + public Integer getProduct_skn() {
  24 + return product_skn;
  25 + }
  26 +
  27 + public void setProduct_skn(Integer product_skn) {
  28 + this.product_skn = product_skn;
  29 + }
  30 +
  31 + public String getProduct_name() {
  32 + return product_name;
  33 + }
  34 +
  35 + public void setProduct_name(String product_name) {
  36 + this.product_name = product_name;
  37 + }
  38 +
  39 + public Double getSales_price() {
  40 + return sales_price;
  41 + }
  42 +
  43 + public void setSales_price(Double sales_price) {
  44 + this.sales_price = sales_price;
  45 + }
  46 +
  47 + public String getDefault_images() {
  48 + return default_images;
  49 + }
  50 +
  51 + public void setDefault_images(String default_images) {
  52 + this.default_images = default_images;
  53 + }
  54 +
  55 + public String getCover_1() {
  56 + return cover_1;
  57 + }
  58 +
  59 + public void setCover_1(String cover_1) {
  60 + this.cover_1 = cover_1;
  61 + }
  62 +
  63 + public String getCover_2() {
  64 + return cover_2;
  65 + }
  66 +
  67 + public void setCover_2(String cover_2) {
  68 + this.cover_2 = cover_2;
  69 + }
  70 +
  71 + public String getGender() {
  72 + return gender;
  73 + }
  74 +
  75 + public void setGender(String gender) {
  76 + this.gender = gender;
  77 + }
  78 +
  79 + public Object getProduct_price_plan_list() {
  80 + return product_price_plan_list;
  81 + }
  82 +
  83 + public void setProduct_price_plan_list(Object product_price_plan_list) {
  84 + this.product_price_plan_list = product_price_plan_list;
  85 + }
  86 +
  87 + public String getBrand_name() {
  88 + return brand_name;
  89 + }
  90 +
  91 + public void setBrand_name(String brand_name) {
  92 + this.brand_name = brand_name;
  93 + }
  94 +
  95 + public String getBrand_ico() {
  96 + return brand_ico;
  97 + }
  98 +
  99 + public void setBrand_ico(String brand_ico) {
  100 + this.brand_ico = brand_ico;
  101 + }
  102 + }
  103 +
  104 + public Integer getShop_id() {
  105 + return shop_id;
  106 + }
  107 +
  108 + public void setShop_id(Integer shop_id) {
  109 + this.shop_id = shop_id;
  110 + }
  111 +
  112 + public String getShop_name() {
  113 + return shop_name;
  114 + }
  115 +
  116 + public void setShop_name(String shop_name) {
  117 + this.shop_name = shop_name;
  118 + }
  119 +
  120 + public String getHr_shop_id() {
  121 + return hr_shop_id;
  122 + }
  123 +
  124 + public void setHr_shop_id(String hr_shop_id) {
  125 + this.hr_shop_id = hr_shop_id;
  126 + }
  127 +
  128 + public List<ShopProduct> getShop_product_list() {
  129 + return shop_product_list;
  130 + }
  131 +
  132 + public void setShop_product_list(List<ShopProduct> shop_product_list) {
  133 + this.shop_product_list = shop_product_list;
  134 + }
  135 +}
  1 +package com.yoho.search.recall.scene.models.req;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.yoho.search.base.utils.Transfer;
  5 +import com.yoho.search.recall.scene.models.common.AbstractCacheRequestResponse;
  6 +
  7 +public class SknImgsRequestResponse extends AbstractCacheRequestResponse<SknImgsResquest, SknImgsResponse> {
  8 +
  9 + public SknImgsRequestResponse(SknImgsResquest request) {
  10 + super(request);
  11 + }
  12 +
  13 + @Override
  14 + public Transfer<String, SknImgsResponse> getToResponseTransfer() {
  15 + return (v) -> JSON.parseObject(v, SknImgsResponse.class);
  16 + }
  17 +
  18 + @Override
  19 + public Transfer<SknImgsResponse, String> getFromResponseTransfer() {
  20 + return (v) -> JSON.toJSONString(v);
  21 + }
  22 +}
  1 +package com.yoho.search.recall.scene.models.req;
  2 +
  3 +public class SknImgsResponse {
  4 + private String default_images;
  5 + private String skn_default_img;
  6 + private String cover_1;
  7 + private String cover_2;
  8 + private String gender;
  9 +
  10 + public String getDefault_images() {
  11 + return default_images;
  12 + }
  13 +
  14 + public void setDefault_images(String default_images) {
  15 + this.default_images = default_images;
  16 + }
  17 +
  18 + public String getSkn_default_img() {
  19 + return skn_default_img;
  20 + }
  21 +
  22 + public void setSkn_default_img(String skn_default_img) {
  23 + this.skn_default_img = skn_default_img;
  24 + }
  25 +
  26 + public String getCover_1() {
  27 + return cover_1;
  28 + }
  29 +
  30 + public void setCover_1(String cover_1) {
  31 + this.cover_1 = cover_1;
  32 + }
  33 +
  34 + public String getCover_2() {
  35 + return cover_2;
  36 + }
  37 +
  38 + public void setCover_2(String cover_2) {
  39 + this.cover_2 = cover_2;
  40 + }
  41 +
  42 + public String getGender() {
  43 + return gender;
  44 + }
  45 +
  46 + public void setGender(String gender) {
  47 + this.gender = gender;
  48 + }
  49 +}
  1 +package com.yoho.search.recall.scene.models.req;
  2 +
  3 +import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
  4 +import com.yoho.search.base.utils.ProductIndexEsField;
  5 +import com.yoho.search.recall.scene.constants.CacheTimeConstants;
  6 +import com.yoho.search.recall.scene.models.common.ICacheRequest;
  7 +
  8 +import java.util.Arrays;
  9 +import java.util.List;
  10 +
  11 +public class SknImgsResquest implements ICacheRequest {
  12 + private static final List<String> includeFields = Arrays.asList(ProductIndexEsField.productSkn,ProductIndexEsField.defaultImages, ProductIndexEsField.sknDefaultImg, ProductIndexEsField.goodsList,ProductIndexEsField.gender);
  13 + private Integer productSkn;
  14 +
  15 + public SknImgsResquest(Integer productSkn){
  16 + this.productSkn = productSkn;
  17 + }
  18 +
  19 + @Override
  20 + public RedisKeyBuilder redisKeyBuilder() {
  21 + return RedisKeyBuilder.newInstance().appendFixed("YOHOSEARCH:").appendFixed("SKN_DEFAULT_IMG:").appendVar(cacheTimeInMinute()).appendFixed(":").appendVar(productSkn);
  22 + }
  23 +
  24 + @Override
  25 + public int cacheTimeInMinute() {
  26 + return CacheTimeConstants.CACHE_60_MINUTE;
  27 + }
  28 +
  29 + public Integer getProductSkn() {
  30 + return productSkn;
  31 + }
  32 +
  33 + public List<String> includeFields(){
  34 + return includeFields;
  35 + }
  36 +
  37 +}
  1 +package com.yoho.search.restapi.others;
  2 +
  3 +import com.yoho.search.common.utils.HttpServletRequestUtils;
  4 +import com.yoho.search.models.SearchApiResult;
  5 +import com.yoho.search.service.base.SearchRequestParams;
  6 +import com.yoho.search.service.service.impl.SearchHongRenService;
  7 +import com.yoho.search.service.service.impl.SearchSortGroupService;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.web.bind.annotation.RequestMapping;
  10 +import org.springframework.web.bind.annotation.RequestMethod;
  11 +import org.springframework.web.bind.annotation.RestController;
  12 +
  13 +import javax.servlet.http.HttpServletRequest;
  14 +import java.util.Map;
  15 +
  16 +@RestController
  17 +@RequestMapping("/hr")
  18 +public class HrDistributionController {
  19 +
  20 + @Autowired
  21 + private SearchSortGroupService searchSortGroupService;
  22 + @Autowired
  23 + private SearchHongRenService searchHongRenService;
  24 + /**
  25 + * 对分类进行分组查询
  26 + * @param request
  27 + * @return
  28 + */
  29 + @RequestMapping(method = RequestMethod.GET, value = "/sortgroup")
  30 + public SearchApiResult sortGroup(HttpServletRequest request) {
  31 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  32 + if (!checkRequestParam(paramMap)) {
  33 + return new SearchApiResult().setCode(400).setMessage("入参缺少hrShopId参数");
  34 + }
  35 + return searchSortGroupService.sortGroup(paramMap);
  36 + }
  37 +
  38 + @RequestMapping(method = RequestMethod.GET, value = "/shopList")
  39 + public SearchApiResult getShopList(HttpServletRequest request) {
  40 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  41 + if (!checkRequestParam(paramMap)) {
  42 + return new SearchApiResult().setCode(400).setMessage("入参缺少hrShopId参数");
  43 + }
  44 + return searchHongRenService.shopList(paramMap);
  45 + }
  46 +
  47 + @RequestMapping(method = RequestMethod.GET, value = "/productList")
  48 + public SearchApiResult productList(HttpServletRequest request) {
  49 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  50 + if (!checkRequestParam(paramMap)) {
  51 + return new SearchApiResult().setCode(400).setMessage("入参缺少hrShopId参数");
  52 + }
  53 + SearchApiResult searchApiResult = searchHongRenService.productList(paramMap);
  54 + return searchApiResult;
  55 + }
  56 +
  57 + @RequestMapping(method = RequestMethod.GET, value = "/productListForFuzzy")
  58 + public SearchApiResult fuzzyProductList(HttpServletRequest request) {
  59 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  60 + if (!checkRequestParam(paramMap)) {
  61 + return new SearchApiResult().setCode(400).setMessage("入参缺少hrShopId参数");
  62 + }
  63 + SearchApiResult searchApiResult = searchHongRenService.productListForFuzzy(paramMap);
  64 + return searchApiResult;
  65 + }
  66 +
  67 + private boolean checkRequestParam(Map<String, String> paramMap) {
  68 + return paramMap.containsKey(SearchRequestParams.PRODUCTINDEX_HRSHOPID);
  69 + }
  70 +
  71 +
  72 +}
@@ -52,4 +52,11 @@ public class CommonSecneController { @@ -52,4 +52,11 @@ public class CommonSecneController {
52 Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request); 52 Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
53 return commonSceneService.aggregations(paramMap); 53 return commonSceneService.aggregations(paramMap);
54 } 54 }
  55 +
  56 + @RequestMapping(method = RequestMethod.GET, value = "/common/sknImgs")
  57 + @ResponseBody
  58 + public SearchApiResult sknImgs(HttpServletRequest request) {
  59 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  60 + return commonSceneService.sknImgs(paramMap);
  61 + }
55 } 62 }
@@ -141,4 +141,8 @@ public class AggregationFactoryService { @@ -141,4 +141,8 @@ public class AggregationFactoryService {
141 public IAggregation getCustomizeTagAggregation(Map<String, String> paramMap) { 141 public IAggregation getCustomizeTagAggregation(Map<String, String> paramMap) {
142 return new CustomizeTagAggregation(customizeTagBaseService, paramMap); 142 return new CustomizeTagAggregation(customizeTagBaseService, paramMap);
143 } 143 }
  144 +
  145 + public IAggregation getShopAndSknAggregation(int aggCount) {
  146 + return new ShopAndSknAggregation(aggCount);
  147 + }
144 } 148 }
  1 +package com.yoho.search.service.aggregations.impls;
  2 +
  3 +import com.yoho.search.base.utils.ProductIndexEsField;
  4 +import org.apache.commons.lang3.StringUtils;
  5 +import org.elasticsearch.search.aggregations.Aggregation;
  6 +import org.springframework.util.CollectionUtils;
  7 +
  8 +import java.util.*;
  9 +import java.util.stream.Collectors;
  10 +
  11 +public class ShopAndSknAggregation extends AbstractSingleFieldAggregation{
  12 +
  13 + public ShopAndSknAggregation(int count) {
  14 + super(count);
  15 + }
  16 +
  17 + @Override
  18 + public String aggName() {
  19 + return "shopAndSknAgg";
  20 + }
  21 +
  22 + @Override
  23 + public String filterName() {
  24 + return "shop";
  25 + }
  26 +
  27 + protected String getField() {
  28 + return ProductIndexEsField.shopId;
  29 + }
  30 +
  31 + @Override
  32 + public Object getAggregationResponseMap(Map<String, Aggregation> aggMaps) {
  33 + List<String> shopIdList = (List<String>) super.getAggregationResponseMap(aggMaps);
  34 + List<Integer> shopIdResult = new ArrayList<>();
  35 + if (!CollectionUtils.isEmpty(shopIdList)) {
  36 + shopIdResult = shopIdList.stream().filter(StringUtils::isNotBlank).map(Integer::valueOf).filter(shopId -> shopId > 0).collect(Collectors.toList());
  37 + }
  38 + return shopIdResult;
  39 + }
  40 +
  41 +
  42 +}
@@ -53,7 +53,7 @@ public class SearchCommonService implements ApplicationEventPublisherAware { @@ -53,7 +53,7 @@ public class SearchCommonService implements ApplicationEventPublisherAware {
53 } 53 }
54 QueryBuilder filter = searchParam.getFiter(); 54 QueryBuilder filter = searchParam.getFiter();
55 String filterString = (filter == null ? "" : filter.toString()); 55 String filterString = (filter == null ? "" : filter.toString());
56 - if (!filterString.contains(ProductIndexEsField.poolId)) { 56 + if (!filterString.contains(ProductIndexEsField.poolIds)) {
57 return; 57 return;
58 } 58 }
59 publisher.publishEvent(new SearchEvent(indexName, EventReportEnum.SEARCHCOMMONSERVICE_DOSEARCH.getFunctionName(), EventReportEnum.SEARCHCOMMONSERVICE_DOSEARCH 59 publisher.publishEvent(new SearchEvent(indexName, EventReportEnum.SEARCHCOMMONSERVICE_DOSEARCH.getFunctionName(), EventReportEnum.SEARCHCOMMONSERVICE_DOSEARCH
@@ -129,4 +129,6 @@ public class SearchRequestParams { @@ -129,4 +129,6 @@ public class SearchRequestParams {
129 public static final String PROMOTIONINDEX_ISDEL = "isDel"; 129 public static final String PROMOTIONINDEX_ISDEL = "isDel";
130 public static final String PROMOTIONINDEX_COMMONBANNER= "commonBanner"; 130 public static final String PROMOTIONINDEX_COMMONBANNER= "commonBanner";
131 131
  132 + public static final String PRODUCTINDEX_HRSHOPID= "hrShopId";
  133 +
132 } 134 }
@@ -279,7 +279,7 @@ public class ProductIndexBaseService { @@ -279,7 +279,7 @@ public class ProductIndexBaseService {
279 */ 279 */
280 public List<Map<String, Object>> getProductListWithPricePlan(List<Map<String, Object>> productEsSourceList) { 280 public List<Map<String, Object>> getProductListWithPricePlan(List<Map<String, Object>> productEsSourceList) {
281 if (productEsSourceList == null || productEsSourceList.isEmpty()) { 281 if (productEsSourceList == null || productEsSourceList.isEmpty()) {
282 - return new ArrayList<Map<String, Object>>(); 282 + return new ArrayList<>();
283 } 283 }
284 // 获取搜索结果的skn,根据它们来获取product_price_plan 284 // 获取搜索结果的skn,根据它们来获取product_price_plan
285 String[] sknStr = new String[productEsSourceList.size()]; 285 String[] sknStr = new String[productEsSourceList.size()];
@@ -377,22 +377,6 @@ public class SearchCommonHelper { @@ -377,22 +377,6 @@ public class SearchCommonHelper {
377 } 377 }
378 378
379 /** 379 /**
380 - * 构造商品池相关的过滤条件  
381 - *  
382 - * @param paramMap  
383 - * @return  
384 - */  
385 - public BoolQueryBuilder getPoolIdTermsBuilder(Map<String, String> paramMap) {  
386 - // 增加商品池相关的过滤条件  
387 - if (paramMap.containsKey("filter_poolId") && StringUtils.isNotBlank("filter_poolId")) {  
388 - BoolQueryBuilder nestedBoolFilter = QueryBuilders.boolQuery();  
389 - nestedBoolFilter.must(QueryBuilders.termQuery("pools.pool_id", paramMap.get("filter_poolId")));  
390 - return nestedBoolFilter;  
391 - }  
392 - return null;  
393 - }  
394 -  
395 - /**  
396 * 自定义标签过滤 380 * 自定义标签过滤
397 * 381 *
398 * @param paramMap 382 * @param paramMap
@@ -469,7 +469,7 @@ public class SearchServiceHelper { @@ -469,7 +469,7 @@ public class SearchServiceHelper {
469 469
470 // 处理filter_poolId 470 // 处理filter_poolId
471 if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_FILTER_POOLID)) { 471 if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_FILTER_POOLID)) {
472 - boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.poolId, paramMap.get(SearchRequestParams.PARAM_SEARCH_FILTER_POOLID).split(","))); 472 + boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.poolIds, paramMap.get(SearchRequestParams.PARAM_SEARCH_FILTER_POOLID).split(",")));
473 } 473 }
474 474
475 // 处理not_productSkn 475 // 处理not_productSkn
@@ -524,6 +524,11 @@ public class SearchServiceHelper { @@ -524,6 +524,11 @@ public class SearchServiceHelper {
524 } 524 }
525 } 525 }
526 } 526 }
  527 + //hrShopIds
  528 + if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PRODUCTINDEX_HRSHOPID)) {
  529 + int[] hrShopIds = ConvertUtils.stringToIntArray(paramMap.get(SearchRequestParams.PRODUCTINDEX_HRSHOPID), ",");
  530 + boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.hrShopIds, hrShopIds));
  531 + }
527 532
528 if (boolFilter.hasClauses()) { 533 if (boolFilter.hasClauses()) {
529 return boolFilter; 534 return boolFilter;
@@ -239,14 +239,6 @@ public class SearchSortHelper { @@ -239,14 +239,6 @@ public class SearchSortHelper {
239 activitySort.setNestedFilter(activitiesTermsBuilder); 239 activitySort.setNestedFilter(activitiesTermsBuilder);
240 } 240 }
241 sortBuilders.add(activitySort); 241 sortBuilders.add(activitySort);
242 - } else if (fieldName.contains("pools")) {  
243 - BoolQueryBuilder poolsTermsBuilder = searchCommonHelper.getPoolIdTermsBuilder(paramMap);  
244 - String flag = sortOrder.toString().equals("desc") ? "_last" : "_first";  
245 - FieldSortBuilder poolsFieldSortBuilder = SortBuilders.fieldSort(fieldName).order(sortOrder).setNestedPath("pools").missing(flag);  
246 - if (poolsFieldSortBuilder != null) {  
247 - poolsFieldSortBuilder.setNestedFilter(poolsTermsBuilder);  
248 - }  
249 - sortBuilders.add(poolsFieldSortBuilder);  
250 } else { 242 } else {
251 this.addSortBuildSorts(sortBuilders, filteredFieldNames, fieldName, sortOrder); 243 this.addSortBuildSorts(sortBuilders, filteredFieldNames, fieldName, sortOrder);
252 } 244 }
@@ -12,10 +12,12 @@ import com.yoho.search.service.base.ProductListSortService; @@ -12,10 +12,12 @@ import com.yoho.search.service.base.ProductListSortService;
12 import com.yoho.search.service.base.SearchCommonService; 12 import com.yoho.search.service.base.SearchCommonService;
13 import com.yoho.search.service.base.SearchRequestParams; 13 import com.yoho.search.service.base.SearchRequestParams;
14 import com.yoho.search.service.base.index.ProductIndexBaseService; 14 import com.yoho.search.service.base.index.ProductIndexBaseService;
  15 +import com.yoho.search.service.helper.ProductListHelper;
15 import com.yoho.search.service.helper.SearchCommonHelper; 16 import com.yoho.search.service.helper.SearchCommonHelper;
16 import com.yoho.search.service.helper.SearchParamHelper; 17 import com.yoho.search.service.helper.SearchParamHelper;
17 import com.yoho.search.service.helper.SearchSortHelper; 18 import com.yoho.search.service.helper.SearchSortHelper;
18 import com.yoho.search.service.scene.common.AbstractCacheAbleService; 19 import com.yoho.search.service.scene.common.AbstractCacheAbleService;
  20 +import org.apache.commons.collections.MapUtils;
19 import org.apache.commons.lang.StringUtils; 21 import org.apache.commons.lang.StringUtils;
20 import org.slf4j.Logger; 22 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory; 23 import org.slf4j.LoggerFactory;
@@ -27,99 +29,61 @@ import java.util.Map; @@ -27,99 +29,61 @@ import java.util.Map;
27 29
28 @Service 30 @Service
29 public class FuzzySceneProductListService extends AbstractCacheAbleService { 31 public class FuzzySceneProductListService extends AbstractCacheAbleService {
30 - private static final Logger logger = LoggerFactory.getLogger(ProductListSwitchService.class);  
31 32
32 - @Autowired  
33 - private SearchCommonService searchCommonService;  
34 - @Autowired  
35 - private ProductIndexBaseService productIndexBaseService;  
36 - @Autowired  
37 - private SearchParamHelper searchParamHelper;  
38 - @Autowired  
39 - private SearchSortHelper searchSortHelper;  
40 - @Autowired  
41 - private ProductListSortService productListSortService;  
42 - @Autowired  
43 - private SearchCommonHelper searchCommonHelper; 33 + private static final Logger logger = LoggerFactory.getLogger(ProductListSwitchService.class);
44 34
45 - @Override  
46 - public SearchCache getSearchCache() {  
47 - return searchCacheFactory.getFuzzySearchCache();  
48 - } 35 + @Autowired
  36 + private SearchCommonService searchCommonService;
  37 + @Autowired
  38 + private SearchCommonHelper searchCommonHelper;
  39 + @Autowired
  40 + private ProductListHelper productListHelper;
49 41
50 - /**  
51 - * 获取商品列表  
52 - *  
53 - * @param paramMap  
54 - * @return  
55 - * @throws Exception  
56 - */  
57 - public SearchApiResult productList(Map<String, String> paramMap) {  
58 - try {  
59 - // 0)定义页面为模糊搜索的页面  
60 - paramMap.put(SearchRequestParams.PARAM_SEARCH_PAGEID, SearchPageIdDefine.PAGE_ID_SEARCH); 42 + @Override
  43 + public SearchCache getSearchCache() {
  44 + return searchCacheFactory.getFuzzySearchCache();
  45 + }
61 46
62 - // 1)构造搜索参数  
63 - SearchParam searchParam = this.buildProductListSearchParam(paramMap); 47 + /**
  48 + * 模糊搜索获取商品列表
  49 + *
  50 + * @param paramMap
  51 + * @return
  52 + * @throws Exception
  53 + */
  54 + public SearchApiResult productList(Map<String, String> paramMap) {
  55 + try {
  56 + // 1)定义页面为模糊搜索的页面
  57 + paramMap.put(SearchRequestParams.PARAM_SEARCH_PAGEID, SearchPageIdDefine.PAGE_ID_SEARCH);
64 58
65 - // 2)从缓存中获取数据  
66 - final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;  
67 - JSONObject cacheObject = searchCacheService.getJSONObjectFromCache(this.searchCache, indexName, searchParam);  
68 - if (cacheObject != null) {  
69 - SearchCacheMatchLogger.doSearchCacheMatchLog("/scene/productList.json", paramMap);  
70 - return new SearchApiResult().setData(cacheObject);  
71 - } 59 + // 2)构造搜索参数
  60 + SearchParam searchParam = productListHelper.buildProductListSearchParam(paramMap, true);
72 61
73 - // 3)查询ES  
74 - SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);  
75 - if (searchResult == null) {  
76 - return new SearchApiResult().setCode(500).setMessage("execption");  
77 - } 62 + // 3)从缓存中获取数据
  63 + final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
  64 + JSONObject cacheObject = searchCacheService.getJSONObjectFromCache(this.searchCache, indexName, searchParam);
  65 + if (cacheObject != null) {
  66 + SearchCacheMatchLogger.doSearchCacheMatchLog("/scene/productList.json", paramMap);
  67 + return new SearchApiResult().setData(cacheObject);
  68 + }
78 69
79 - // 4)构造返回结果  
80 - JSONObject dataMap = new JSONObject();  
81 - dataMap.put("total", searchResult.getTotal());  
82 - dataMap.put("page", searchResult.getPage());  
83 - dataMap.put("page_size", searchParam.getSize());  
84 - dataMap.put("page_total", searchResult.getTotalPage());  
85 - List<Map<String, Object>> product_list = productIndexBaseService.getProductListWithPricePlan(searchResult.getResultList());  
86 - if(searchCommonHelper.isOrderEmpty(paramMap)){  
87 - product_list = productListSortService.sortProductList(product_list);// 处理一下商品的顺序;  
88 - }  
89 - //加入到手价字段  
90 - product_list = productIndexBaseService.getProductListWithPriceInHand(product_list);  
91 - dataMap.put("product_list",product_list); 70 + // 4)查询ES
  71 + SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
  72 + if (searchResult == null) {
  73 + return new SearchApiResult().setCode(500).setMessage("execption");
  74 + }
92 75
93 - // 5)将结果存进缓存  
94 - searchCacheService.addJSONObjectToCache(this.searchCache, indexName, searchParam, dataMap);  
95 - return new SearchApiResult().setData(dataMap);  
96 - } catch (Exception e) {  
97 - logger.error(e.getMessage(), e);  
98 - return new SearchApiResult().setCode(500).setMessage("scene productList exception").setData(new JSONObject());  
99 - }  
100 - } 76 + // 5)构造返回结果
  77 + boolean needResort = searchCommonHelper.isOrderEmpty(paramMap) ? true : false;
  78 + JSONObject productListResult = productListHelper.buildProductListResult(searchResult, searchParam.getSize(), needResort);
101 79
102 - private SearchParam buildProductListSearchParam(Map<String, String> paramMap) throws Exception {  
103 - // 1)验证查询条数  
104 - int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));  
105 - int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));  
106 - if (page < 1 || pageSize < 0) {  
107 - throw new IllegalArgumentException("分页参数不合法");  
108 - }  
109 - if (pageSize > 100) {  
110 - pageSize = 100;  
111 - }  
112 - // 2)构建基本查询参数  
113 - SearchParam searchParam = searchParamHelper.buildWithPersional(paramMap, true);  
114 - searchParam.setAggregationBuilders(null);  
115 - searchParam.setOffset((page - 1) * pageSize);  
116 - searchParam.setSize(pageSize);  
117 - // 3)设置排序字段  
118 - searchParam.setSortBuilders(searchSortHelper.buildSortList(paramMap));  
119 - // 4)设置返回的参数【节省带宽】  
120 - List<String> includeFields = productIndexBaseService.getProductIndexIncludeFields();  
121 - searchParam.setIncludeFields(includeFields);  
122 - return searchParam;  
123 - } 80 + // 6)将结果存进缓存
  81 + searchCacheService.addJSONObjectToCache(this.searchCache, indexName, searchParam, productListResult);
  82 + return new SearchApiResult().setData(productListResult);
  83 + } catch (Exception e) {
  84 + logger.error(e.getMessage(), e);
  85 + return new SearchApiResult().setCode(500).setMessage("scene productList exception").setData(new JSONObject());
  86 + }
  87 + }
124 88
125 } 89 }
1 package com.yoho.search.service.scene; 1 package com.yoho.search.service.scene;
2 2
  3 +import com.google.common.base.Splitter;
3 import com.yoho.search.base.utils.SearchPageIdDefine; 4 import com.yoho.search.base.utils.SearchPageIdDefine;
4 import com.yoho.search.common.utils.SearchApiResultUtils; 5 import com.yoho.search.common.utils.SearchApiResultUtils;
5 import com.yoho.search.models.SearchApiResult; 6 import com.yoho.search.models.SearchApiResult;
  7 +import com.yoho.search.recall.scene.beans.cache.SknImgsCacheBean;
  8 +import com.yoho.search.recall.scene.models.req.SknImgsResponse;
  9 +import com.yoho.search.service.base.SearchRequestParams;
6 import com.yoho.search.service.list.ProductListSwitchService; 10 import com.yoho.search.service.list.ProductListSwitchService;
7 import com.yoho.search.service.scene.common.AbstractSceneService; 11 import com.yoho.search.service.scene.common.AbstractSceneService;
8 import com.yoho.search.service.scene.common.SceneRecommendBrandsService; 12 import com.yoho.search.service.scene.common.SceneRecommendBrandsService;
9 import com.yoho.search.service.scene.common.SceneSelectionsService; 13 import com.yoho.search.service.scene.common.SceneSelectionsService;
  14 +import org.apache.commons.lang3.StringUtils;
10 import org.slf4j.Logger; 15 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 16 import org.slf4j.LoggerFactory;
12 import org.springframework.beans.factory.annotation.Autowired; 17 import org.springframework.beans.factory.annotation.Autowired;
13 import org.springframework.stereotype.Service; 18 import org.springframework.stereotype.Service;
14 19
  20 +import java.util.Collections;
15 import java.util.Map; 21 import java.util.Map;
16 22
17 @Service 23 @Service
@@ -25,6 +31,8 @@ public class CommonSceneService extends AbstractSceneService { @@ -25,6 +31,8 @@ public class CommonSceneService extends AbstractSceneService {
25 private SceneSelectionsService sceneSelectionsService; 31 private SceneSelectionsService sceneSelectionsService;
26 @Autowired 32 @Autowired
27 private SceneRecommendBrandsService sceneRecommendBrandsService; 33 private SceneRecommendBrandsService sceneRecommendBrandsService;
  34 + @Autowired
  35 + private SknImgsCacheBean sknImgsCacheBean;
28 36
29 @Override 37 @Override
30 public String pageId() { 38 public String pageId() {
@@ -63,4 +71,14 @@ public class CommonSceneService extends AbstractSceneService { @@ -63,4 +71,14 @@ public class CommonSceneService extends AbstractSceneService {
63 return SearchApiResultUtils.errorSearchApiResult("CommonAggregations", paramMap, e); 71 return SearchApiResultUtils.errorSearchApiResult("CommonAggregations", paramMap, e);
64 } 72 }
65 } 73 }
  74 +
  75 + public SearchApiResult sknImgs(Map<String, String> paramMap) {
  76 + SearchApiResult searchApiResult = new SearchApiResult().setCode(200).setMessage("skn defalut image List.").setData(Collections.EMPTY_MAP);
  77 + String productSkn = paramMap.get(SearchRequestParams.PARAM_SEARCH_PRODUCT_SKN);
  78 + if (StringUtils.isNotEmpty(productSkn) && productSkn.split(",").length > 0) {
  79 + Map<String, SknImgsResponse> result = sknImgsCacheBean.querySknImgs(Splitter.on(",").trimResults().splitToList(productSkn));
  80 + searchApiResult.setData(result);
  81 + }
  82 + return searchApiResult;
  83 + }
66 } 84 }
1 package com.yoho.search.service.service; 1 package com.yoho.search.service.service;
2 2
  3 +import com.alibaba.fastjson.JSON;
3 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
  5 +import com.alibaba.fastjson.TypeReference;
4 import com.yoho.error.event.SearchEvent; 6 import com.yoho.error.event.SearchEvent;
5 import com.yoho.search.base.utils.EventReportEnum; 7 import com.yoho.search.base.utils.EventReportEnum;
6 import com.yoho.search.base.utils.ISearchConstants; 8 import com.yoho.search.base.utils.ISearchConstants;
@@ -9,11 +11,18 @@ import com.yoho.search.core.es.agg.IAggregation; @@ -9,11 +11,18 @@ import com.yoho.search.core.es.agg.IAggregation;
9 import com.yoho.search.core.es.model.SearchParam; 11 import com.yoho.search.core.es.model.SearchParam;
10 import com.yoho.search.core.es.model.SearchResult; 12 import com.yoho.search.core.es.model.SearchResult;
11 import com.yoho.search.core.es.utils.IgnoreSomeException; 13 import com.yoho.search.core.es.utils.IgnoreSomeException;
  14 +import com.yoho.search.recall.scene.beans.cache.ShopProductCacheBean;
  15 +import com.yoho.search.recall.scene.models.common.ParamQueryFilter;
  16 +import com.yoho.search.recall.scene.models.req.ShopProductRequest;
  17 +import com.yoho.search.recall.scene.models.req.ShopProductResponse;
12 import com.yoho.search.service.aggregations.impls.AggregationFactoryService; 18 import com.yoho.search.service.aggregations.impls.AggregationFactoryService;
13 import com.yoho.search.service.base.SearchCommonService; 19 import com.yoho.search.service.base.SearchCommonService;
14 import com.yoho.search.service.base.SearchRequestParams; 20 import com.yoho.search.service.base.SearchRequestParams;
  21 +import com.yoho.search.service.helper.SearchCommonHelper;
15 import com.yoho.search.service.helper.SearchParamHelper; 22 import com.yoho.search.service.helper.SearchParamHelper;
16 import com.yoho.search.service.scene.common.AbstractCacheAbleService; 23 import com.yoho.search.service.scene.common.AbstractCacheAbleService;
  24 +import org.apache.commons.collections.CollectionUtils;
  25 +import org.elasticsearch.index.query.BoolQueryBuilder;
17 import org.elasticsearch.search.aggregations.Aggregation; 26 import org.elasticsearch.search.aggregations.Aggregation;
18 import org.slf4j.Logger; 27 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory; 28 import org.slf4j.LoggerFactory;
@@ -22,8 +31,8 @@ import org.springframework.context.ApplicationEventPublisher; @@ -22,8 +31,8 @@ import org.springframework.context.ApplicationEventPublisher;
22 import org.springframework.context.ApplicationEventPublisherAware; 31 import org.springframework.context.ApplicationEventPublisherAware;
23 import org.springframework.stereotype.Service; 32 import org.springframework.stereotype.Service;
24 33
25 -import java.util.Arrays;  
26 -import java.util.Map; 34 +import java.util.*;
  35 +import java.util.stream.Collectors;
27 36
28 @Service 37 @Service
29 public class AggregationService extends AbstractCacheAbleService implements ApplicationEventPublisherAware { 38 public class AggregationService extends AbstractCacheAbleService implements ApplicationEventPublisherAware {
@@ -36,6 +45,10 @@ public class AggregationService extends AbstractCacheAbleService implements Appl @@ -36,6 +45,10 @@ public class AggregationService extends AbstractCacheAbleService implements Appl
36 private SearchCommonService searchCommonService; 45 private SearchCommonService searchCommonService;
37 @Autowired 46 @Autowired
38 private SearchParamHelper searchParamHelper; 47 private SearchParamHelper searchParamHelper;
  48 + @Autowired
  49 + private ShopProductCacheBean shopSknCacheBean;
  50 + @Autowired
  51 + private SearchCommonHelper searchCommonHelper;
39 52
40 @Override 53 @Override
41 public SearchCache getSearchCache() { 54 public SearchCache getSearchCache() {
@@ -252,4 +265,46 @@ public class AggregationService extends AbstractCacheAbleService implements Appl @@ -252,4 +265,46 @@ public class AggregationService extends AbstractCacheAbleService implements Appl
252 return this.getAggNameAndResponseWithCache(standardAggregation, searchParam); 265 return this.getAggNameAndResponseWithCache(standardAggregation, searchParam);
253 } 266 }
254 267
  268 + /**
  269 + * 获取店铺聚合结果。
  270 + */
  271 + public JSONObject getShopAndSknAggregationResult(Map<String, String> paramMap, int page, int pageSize, int aggCount) throws Exception {
  272 + IAggregation shopAndSknAggregation = aggregationFactoryService.getShopAndSknAggregation(aggCount);
  273 + SearchParam searchParam = this.genSearchParamForAgg(shopAndSknAggregation, paramMap, null, 0);
  274 + JSONObject aggResult = getAggNameAndResponseWithCache(shopAndSknAggregation, searchParam);
  275 + JSONObject dataMap = new JSONObject();
  276 + if (aggResult != null) {
  277 + List<Integer> shopIds = JSON.parseObject(aggResult.getJSONArray("shopAndSknAgg").toJSONString(), new TypeReference<List<Integer>>() {});
  278 + if (CollectionUtils.isNotEmpty(shopIds)) {
  279 + dataMap.put("page", page);
  280 + dataMap.put("page_size", pageSize);
  281 + dataMap.put("total", shopIds.size());
  282 + dataMap.put("page_total", searchCommonHelper.getTotalPage(shopIds.size(), pageSize));
  283 + dataMap.put("shop_product_list", Collections.emptyList());
  284 + List<Integer> subShopIds = subList(shopIds, pageSize, page);
  285 + if (CollectionUtils.isNotEmpty(subShopIds)) {
  286 + List<ShopProductRequest> shopProductRequests = subShopIds.stream().map(shopId -> {
  287 + return new ShopProductRequest(new ParamQueryFilter(searchParam.getQuery(), (BoolQueryBuilder)searchParam.getFiter()), shopId);
  288 + }).collect(Collectors.toList());
  289 + String hrShopIds = paramMap.get(SearchRequestParams.PRODUCTINDEX_HRSHOPID);
  290 + List<ShopProductResponse> responseList = shopSknCacheBean.getShopSknByShopId(shopProductRequests, hrShopIds);
  291 + dataMap.put("shop_product_list", responseList);
  292 + }
  293 + }
  294 + }
  295 + return dataMap;
  296 + }
  297 +
  298 + private List<Integer> subList(List<Integer> sourceList, int pageSize, int page) {
  299 + int fromIndex = pageSize * (page - 1);
  300 + if (fromIndex >= sourceList.size()) {
  301 + return null;
  302 + }
  303 + int toIndex = pageSize * page;
  304 + if (toIndex > sourceList.size()) {
  305 + toIndex = sourceList.size();
  306 + }
  307 + return sourceList.subList(fromIndex, toIndex);
  308 + }
  309 +
255 } 310 }
  1 +package com.yoho.search.service.service.impl;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.yoho.search.common.utils.SearchApiResultUtils;
  5 +import com.yoho.search.models.SearchApiResult;
  6 +import com.yoho.search.service.base.SearchCacheService;
  7 +import com.yoho.search.service.base.SearchRequestParams;
  8 +import com.yoho.search.service.helper.SearchCommonHelper;
  9 +import com.yoho.search.service.helper.SearchKeyWordHelper;
  10 +import com.yoho.search.service.list.FuzzySceneProductListService;
  11 +import com.yoho.search.service.list.ProductListSwitchService;
  12 +import com.yoho.search.service.scene.common.AbstractSceneService;
  13 +import com.yoho.search.service.service.AggregationService;
  14 +import org.apache.commons.lang3.StringUtils;
  15 +import org.springframework.beans.factory.annotation.Autowired;
  16 +import org.springframework.stereotype.Service;
  17 +
  18 +import java.util.Map;
  19 +
  20 +@Service
  21 +public class SearchHongRenService extends AbstractSceneService {
  22 +
  23 + @Autowired
  24 + protected SearchCacheService searchCacheService;
  25 + @Autowired
  26 + private AggregationService aggregationService;
  27 + @Autowired
  28 + private ProductListSwitchService productListSwitchService;
  29 + @Autowired
  30 + private FuzzySceneProductListService fuzzySceneProductListService;
  31 + @Autowired
  32 + private SearchCommonHelper searchCommonHelper;
  33 + @Autowired
  34 + private SearchKeyWordHelper searchKeyWordService;
  35 +
  36 + public SearchApiResult shopList(Map<String, String> paramMap) {
  37 + int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
  38 + int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
  39 + if (page < 1 || pageSize < 0 || page * pageSize > 1000000) {
  40 + return new SearchApiResult().setCode(400).setMessage("分页参数不合法");
  41 + }
  42 + if (pageSize > 100) {
  43 + paramMap.put("viewNum", "100");
  44 + pageSize = 100;
  45 + }
  46 + SearchApiResult searchApiResult = new SearchApiResult().setCode(200).setMessage("Shop product List .");
  47 + try {
  48 + JSONObject dataMap = aggregationService.getShopAndSknAggregationResult(paramMap, page, pageSize, 10000);
  49 + searchApiResult.setData(dataMap);
  50 + } catch (Exception e) {
  51 + return new SearchApiResult().setData(null).setMessage("ShopProductList Exception").setCode(500);
  52 + }
  53 + return searchApiResult;
  54 + }
  55 +
  56 + public SearchApiResult productList(Map<String, String> paramMap) {
  57 + try {
  58 + // 1、添加默认参数
  59 + addParamsToParamMap(paramMap);
  60 + return productListSwitchService.productList(newParamMap(paramMap));
  61 + } catch (Exception e) {
  62 + return new SearchApiResult().setData(null).setMessage("hrSortProductList Exception").setCode(500);
  63 + }
  64 + }
  65 +
  66 + public SearchApiResult productListForFuzzy(Map<String, String> paramMap) {
  67 + try {
  68 + // 1、参数校验
  69 + if (StringUtils.isBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_QUERY))) {
  70 + return new SearchApiResult().setCode(400).setMessage("请传query参数");
  71 + }
  72 + // 2、添加默认参数
  73 + this.addParamsToParamMap(paramMap);
  74 + // 3、获取商品列表
  75 + SearchApiResult productListResult = fuzzySceneProductListService.productList(this.newParamMap(paramMap));
  76 + // 7、模糊搜索页记录关键字对应的查询结果
  77 + String queryWord = paramMap.get("query");
  78 + if (!StringUtils.isBlank(queryWord) && !searchCommonHelper.isQuerySknOrSku(queryWord)) {
  79 + long total = ((JSONObject) productListResult.getData()).getLongValue("total");
  80 + searchKeyWordService.recordKeyWordByResultCount(queryWord, total);
  81 + }
  82 + return productListResult;
  83 + } catch (Exception e) {
  84 + return SearchApiResultUtils.errorSearchApiResult("hrfuzzyProductList", paramMap, e);
  85 + }
  86 + }
  87 +
  88 + @Override
  89 + public void addParamsToParamMap(Map<String, String> paramMap) {
  90 + super.addDefaultParamsToParamMap(paramMap);
  91 + }
  92 +
  93 + @Override
  94 + public String pageId() {
  95 + return null;
  96 + }
  97 +
  98 + @Override
  99 + public SearchApiResult aggregations(Map<String, String> paramMap) {
  100 + return null;
  101 + }
  102 +
  103 +
  104 +}