Authored by hugufei

找相似代码优化【共用一份缓存即可】

@@ -5,6 +5,8 @@ import java.util.Map; @@ -5,6 +5,8 @@ import java.util.Map;
5 import javax.servlet.http.HttpServletRequest; 5 import javax.servlet.http.HttpServletRequest;
6 6
7 import com.yoho.search.service.scene.searchlike.BigdataSimilarSknService; 7 import com.yoho.search.service.scene.searchlike.BigdataSimilarSknService;
  8 +import com.yoho.search.service.scene.searchlike.SearchLikeHelper;
  9 +import org.apache.commons.collections.MapUtils;
8 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.beans.factory.annotation.Autowired;
9 import org.springframework.stereotype.Controller; 11 import org.springframework.stereotype.Controller;
10 import org.springframework.web.bind.annotation.RequestMapping; 12 import org.springframework.web.bind.annotation.RequestMapping;
@@ -37,6 +39,8 @@ public class SearchLikeSecneController { @@ -37,6 +39,8 @@ public class SearchLikeSecneController {
37 private SimilarProductService similarProductService; 39 private SimilarProductService similarProductService;
38 @Autowired 40 @Autowired
39 private BigdataSimilarSknService bigdataSimilarSknService; 41 private BigdataSimilarSknService bigdataSimilarSknService;
  42 + @Autowired
  43 + private SearchLikeHelper searchLikeHelper;
40 44
41 @RequestMapping(method = RequestMethod.GET, value = "/searchLike") 45 @RequestMapping(method = RequestMethod.GET, value = "/searchLike")
42 @ResponseBody 46 @ResponseBody
@@ -49,14 +53,18 @@ public class SearchLikeSecneController { @@ -49,14 +53,18 @@ public class SearchLikeSecneController {
49 @ResponseBody 53 @ResponseBody
50 public SearchApiResult searchLikeInShop(HttpServletRequest request) { 54 public SearchApiResult searchLikeInShop(HttpServletRequest request) {
51 Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request); 55 Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
52 - return searchLikeInShopService.searchLikeInShop(paramMap); 56 + int viewNum = MapUtils.getIntValue(paramMap,"viewNum",10);
  57 + SearchApiResult result = searchLikeInShopService.searchLikeInShop(paramMap);
  58 + return searchLikeHelper.buildSearchApiResultWithViewNum(result,viewNum);
53 } 59 }
54 60
55 @RequestMapping(method = RequestMethod.GET, value = "/searchLikeNotInShop") 61 @RequestMapping(method = RequestMethod.GET, value = "/searchLikeNotInShop")
56 @ResponseBody 62 @ResponseBody
57 public SearchApiResult searchLikeNotInShop(HttpServletRequest request) { 63 public SearchApiResult searchLikeNotInShop(HttpServletRequest request) {
58 Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request); 64 Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
59 - return bigdataSimilarSknService.searchLikeSimilarSknNotInShop(paramMap); 65 + int viewNum = MapUtils.getIntValue(paramMap,"viewNum",10);
  66 + SearchApiResult result = bigdataSimilarSknService.searchLikeSimilarSknNotInShop(paramMap);
  67 + return searchLikeHelper.buildSearchApiResultWithViewNum(result,viewNum);
60 } 68 }
61 69
62 70
@@ -38,21 +38,22 @@ public class BigdataSimilarSknService { @@ -38,21 +38,22 @@ public class BigdataSimilarSknService {
38 38
39 /** 39 /**
40 * 获取非重复skn 40 * 获取非重复skn
  41 + *
41 * @param productSknStr 42 * @param productSknStr
42 * @return 43 * @return
43 */ 44 */
44 - private List<String> getDistinctSknList(String productSknStr){ 45 + private List<String> getDistinctSknList(String productSknStr) {
45 List<String> results = new ArrayList<>(); 46 List<String> results = new ArrayList<>();
46 - String [] productSkns = productSknStr.split(",");  
47 - for (String productSkn : productSkns){  
48 - if(!results.contains(productSkn) && StringUtils.isNumeric(productSkn)){ 47 + String[] productSkns = productSknStr.split(",");
  48 + for (String productSkn : productSkns) {
  49 + if (!results.contains(productSkn) && StringUtils.isNumeric(productSkn)) {
49 results.add(productSkn); 50 results.add(productSkn);
50 } 51 }
51 } 52 }
52 return results; 53 return results;
53 } 54 }
54 55
55 - @SearchCacheAble(cacheInMinute = 600, cacheName = "SEARCH_LIKE_NOT_IN_SHOP_SIMILAR", includeParams = { "product_skn", "viewNum" }) 56 + @SearchCacheAble(cacheInMinute = 600, cacheName = "SEARCH_LIKE_NOT_IN_SHOP_SIMILAR", includeParams = {"product_skn"})
56 public SearchApiResult searchLikeSimilarSknNotInShop(Map<String, String> paramMap) { 57 public SearchApiResult searchLikeSimilarSknNotInShop(Map<String, String> paramMap) {
57 try { 58 try {
58 // 1、获取参数 59 // 1、获取参数
@@ -61,7 +62,7 @@ public class BigdataSimilarSknService { @@ -61,7 +62,7 @@ public class BigdataSimilarSknService {
61 return new SearchApiResult().setCode(400).setMessage("请输入SKN"); 62 return new SearchApiResult().setCode(400).setMessage("请输入SKN");
62 } 63 }
63 // 2、检测分页参数【默认30条,最多60条】 64 // 2、检测分页参数【默认30条,最多60条】
64 - int pageSize = searchLikeHelper.getPageSize(paramMap); 65 + int pageSize = 30;
65 // 3、获取当前查询的SKN的基本信息 66 // 3、获取当前查询的SKN的基本信息
66 JSONObject productInfoInEs = searchLikeHelper.getProductInfoInEs(productSkn); 67 JSONObject productInfoInEs = searchLikeHelper.getProductInfoInEs(productSkn);
67 if (productInfoInEs == null) { 68 if (productInfoInEs == null) {
@@ -87,14 +88,14 @@ public class BigdataSimilarSknService { @@ -87,14 +88,14 @@ public class BigdataSimilarSknService {
87 searchParams.add(this.builderSimilarSknSearchParam(productInfoInEs, diffShopActionSimilarSkns, true)); 88 searchParams.add(this.builderSimilarSknSearchParam(productInfoInEs, diffShopActionSimilarSkns, true));
88 89
89 //5.3)文字兜底[性别+不同店铺+文字相似性] 90 //5.3)文字兜底[性别+不同店铺+文字相似性]
90 - searchParams.add( searchLikeHelper.builderSearchLikeNotInShopCharactersSearchParam(productInfoInEs, Arrays.asList(productSkn), pageSize,true)); 91 + searchParams.add(searchLikeHelper.builderSearchLikeNotInShopCharactersSearchParam(productInfoInEs, Arrays.asList(productSkn), pageSize, true));
91 92
92 // 6、获取搜索结果 93 // 6、获取搜索结果
93 List<List<Map<String, Object>>> queryResults = searchLikeHelper.queryProductLists(searchParams); 94 List<List<Map<String, Object>>> queryResults = searchLikeHelper.queryProductLists(searchParams);
94 95
95 // 7、处理图片和行为的顺序 96 // 7、处理图片和行为的顺序
96 - List<Map<String, Object>> diffShopImgSimilarProducts = this.sortProductList(queryResults.get(0),diffShopImgSimilarSkns,pageSize/3);  
97 - List<Map<String, Object>> diffShopActionSimilarProducts = this.sortProductList(queryResults.get(1),diffShopActionSimilarSkns,pageSize/3); 97 + List<Map<String, Object>> diffShopImgSimilarProducts = this.sortProductList(queryResults.get(0), diffShopImgSimilarSkns, pageSize / 3);
  98 + List<Map<String, Object>> diffShopActionSimilarProducts = this.sortProductList(queryResults.get(1), diffShopActionSimilarSkns, pageSize / 3);
98 99
99 // 8、获取临时结果 100 // 8、获取临时结果
100 List<Map<String, Object>> tempProductList = new ArrayList<>(); 101 List<Map<String, Object>> tempProductList = new ArrayList<>();
@@ -102,11 +103,11 @@ public class BigdataSimilarSknService { @@ -102,11 +103,11 @@ public class BigdataSimilarSknService {
102 tempProductList.addAll(diffShopActionSimilarProducts); 103 tempProductList.addAll(diffShopActionSimilarProducts);
103 tempProductList.addAll(queryResults.get(2)); 104 tempProductList.addAll(queryResults.get(2));
104 if (tempProductList.size() > pageSize) { 105 if (tempProductList.size() > pageSize) {
105 - tempProductList = CollectionUtils.safeSubList(tempProductList,0, pageSize); 106 + tempProductList = CollectionUtils.safeSubList(tempProductList, 0, pageSize);
106 } 107 }
107 // 8.1 保留偶数 108 // 8.1 保留偶数
108 - if(tempProductList.size()%2>0){  
109 - tempProductList = CollectionUtils.safeSubList(tempProductList,0, tempProductList.size()-1); 109 + if (tempProductList.size() % 2 > 0) {
  110 + tempProductList = CollectionUtils.safeSubList(tempProductList, 0, tempProductList.size() - 1);
110 } 111 }
111 // 9、构造真实返回结果 112 // 9、构造真实返回结果
112 List<Map<String, Object>> productListResults = new ArrayList<>(); 113 List<Map<String, Object>> productListResults = new ArrayList<>();
@@ -114,10 +115,6 @@ public class BigdataSimilarSknService { @@ -114,10 +115,6 @@ public class BigdataSimilarSknService {
114 productListResults = productListHelper.buildReturnInfoByEsSourceList(tempProductList); 115 productListResults = productListHelper.buildReturnInfoByEsSourceList(tempProductList);
115 } 116 }
116 JSONObject result = new JSONObject(); 117 JSONObject result = new JSONObject();
117 - result.put("page", 1);  
118 - result.put("page_total", 1);  
119 - result.put("page_size", pageSize);  
120 - result.put("total", productListResults.size());  
121 result.put("product_info", searchLikeHelper.genProductInfoResult(productInfoInEs)); 118 result.put("product_info", searchLikeHelper.genProductInfoResult(productInfoInEs));
122 result.put("product_list", productListResults); 119 result.put("product_list", productListResults);
123 return new SearchApiResult().setData(result); 120 return new SearchApiResult().setData(result);
@@ -129,25 +126,26 @@ public class BigdataSimilarSknService { @@ -129,25 +126,26 @@ public class BigdataSimilarSknService {
129 126
130 /** 127 /**
131 * 按productSkn顺序截取商品条数-注意循环引用的问题 128 * 按productSkn顺序截取商品条数-注意循环引用的问题
  129 + *
132 * @param esProductList 130 * @param esProductList
133 * @param sortedProductSkns 131 * @param sortedProductSkns
134 * @param size 132 * @param size
135 * @return 133 * @return
136 */ 134 */
137 - private List<Map<String, Object>> sortProductList(List<Map<String, Object>> esProductList,List<String> sortedProductSkns,int size){ 135 + private List<Map<String, Object>> sortProductList(List<Map<String, Object>> esProductList, List<String> sortedProductSkns, int size) {
138 List<Map<String, Object>> results = new ArrayList<>(); 136 List<Map<String, Object>> results = new ArrayList<>();
139 - if(esProductList==null || esProductList.isEmpty()){ 137 + if (esProductList == null || esProductList.isEmpty()) {
140 return results; 138 return results;
141 } 139 }
142 - if(sortedProductSkns==null || sortedProductSkns.isEmpty() || size<=0){ 140 + if (sortedProductSkns == null || sortedProductSkns.isEmpty() || size <= 0) {
143 return results; 141 return results;
144 } 142 }
145 - Map<String, Map<String, Object>> productMap = CollectionUtils.toMap(esProductList,(product)->MapUtils.getString(product,ProductIndexEsField.productSkn,""));  
146 - for (String productSkn : sortedProductSkns){  
147 - if(productMap.containsKey(productSkn)){ 143 + Map<String, Map<String, Object>> productMap = CollectionUtils.toMap(esProductList, (product) -> MapUtils.getString(product, ProductIndexEsField.productSkn, ""));
  144 + for (String productSkn : sortedProductSkns) {
  145 + if (productMap.containsKey(productSkn)) {
148 results.add(new HashMap<>(productMap.get(productSkn)));//注意循环引用 146 results.add(new HashMap<>(productMap.get(productSkn)));//注意循环引用
149 } 147 }
150 - if(results.size()>=size){ 148 + if (results.size() >= size) {
151 break; 149 break;
152 } 150 }
153 } 151 }
@@ -157,16 +155,17 @@ public class BigdataSimilarSknService { @@ -157,16 +155,17 @@ public class BigdataSimilarSknService {
157 155
158 /** 156 /**
159 * 构建SimilarSknSearchParam[考虑productSkns为空的情况] 157 * 构建SimilarSknSearchParam[考虑productSkns为空的情况]
  158 + *
160 * @param productInfoInEs 159 * @param productInfoInEs
161 * @param productSkns 160 * @param productSkns
162 * @param filterSameSort 161 * @param filterSameSort
163 * @return 162 * @return
164 */ 163 */
165 - private SearchParam builderSimilarSknSearchParam(JSONObject productInfoInEs, List<String> productSkns,boolean filterSameSort) { 164 + private SearchParam builderSimilarSknSearchParam(JSONObject productInfoInEs, List<String> productSkns, boolean filterSameSort) {
166 // 1、设置SearchParam 165 // 1、设置SearchParam
167 SearchParam searchParam = new SearchParam(); 166 SearchParam searchParam = new SearchParam();
168 // 2)设置query和filter 167 // 2)设置query和filter
169 - searchParam.setFiter(this.builderSimilarSknFilter(productInfoInEs, productSkns,filterSameSort)); 168 + searchParam.setFiter(this.builderSimilarSknFilter(productInfoInEs, productSkns, filterSameSort));
170 // 3、设置分页参数 169 // 3、设置分页参数
171 searchParam.setOffset(0); 170 searchParam.setOffset(0);
172 searchParam.setSize(productSkns.size()); 171 searchParam.setSize(productSkns.size());
@@ -176,7 +175,7 @@ public class BigdataSimilarSknService { @@ -176,7 +175,7 @@ public class BigdataSimilarSknService {
176 return searchParam; 175 return searchParam;
177 } 176 }
178 177
179 - private QueryBuilder builderSimilarSknFilter(JSONObject productInfoInEs, List<String> inProductSkns,boolean filterSameSort) { 178 + private QueryBuilder builderSimilarSknFilter(JSONObject productInfoInEs, List<String> inProductSkns, boolean filterSameSort) {
180 String isGlobalInEs = productInfoInEs.getString(ProductIndexEsField.isGlobal); 179 String isGlobalInEs = productInfoInEs.getString(ProductIndexEsField.isGlobal);
181 boolean isGlobal = "Y".equalsIgnoreCase(isGlobalInEs); 180 boolean isGlobal = "Y".equalsIgnoreCase(isGlobalInEs);
182 BoolQueryBuilder boolFilter = searchLikeHelper.genDefaultSearchLikeFilter(null, isGlobal); 181 BoolQueryBuilder boolFilter = searchLikeHelper.genDefaultSearchLikeFilter(null, isGlobal);
1 package com.yoho.search.service.scene.searchlike; 1 package com.yoho.search.service.scene.searchlike;
2 2
  3 +import com.alibaba.fastjson.JSONArray;
3 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
  5 +import com.yoho.search.base.utils.CollectionUtils;
4 import com.yoho.search.base.utils.ISearchConstants; 6 import com.yoho.search.base.utils.ISearchConstants;
5 import com.yoho.search.base.utils.ProductIndexEsField; 7 import com.yoho.search.base.utils.ProductIndexEsField;
6 import com.yoho.search.core.es.model.SearchParam; 8 import com.yoho.search.core.es.model.SearchParam;
7 import com.yoho.search.core.es.model.SearchResult; 9 import com.yoho.search.core.es.model.SearchResult;
  10 +import com.yoho.search.models.SearchApiResult;
8 import com.yoho.search.models.SearchFieldBoost; 11 import com.yoho.search.models.SearchFieldBoost;
9 import com.yoho.search.service.base.SearchCommonService; 12 import com.yoho.search.service.base.SearchCommonService;
10 import com.yoho.search.service.base.index.ProductIndexBaseService; 13 import com.yoho.search.service.base.index.ProductIndexBaseService;
@@ -21,7 +24,6 @@ import org.elasticsearch.search.sort.SortBuilders; @@ -21,7 +24,6 @@ import org.elasticsearch.search.sort.SortBuilders;
21 import org.elasticsearch.search.sort.SortOrder; 24 import org.elasticsearch.search.sort.SortOrder;
22 import org.springframework.beans.factory.annotation.Autowired; 25 import org.springframework.beans.factory.annotation.Autowired;
23 import org.springframework.stereotype.Component; 26 import org.springframework.stereotype.Component;
24 -import org.springframework.util.CollectionUtils;  
25 27
26 import javax.annotation.PostConstruct; 28 import javax.annotation.PostConstruct;
27 import java.util.*; 29 import java.util.*;
@@ -91,6 +93,49 @@ public class SearchLikeHelper { @@ -91,6 +93,49 @@ public class SearchLikeHelper {
91 } 93 }
92 94
93 /** 95 /**
  96 + * 根据缓存结果,截取viewNum
  97 + * @param searchApiResult
  98 + * @param viewNum
  99 + * @return
  100 + */
  101 + public SearchApiResult buildSearchApiResultWithViewNum(SearchApiResult searchApiResult,int viewNum) {
  102 + //1、结果判断
  103 + if(searchApiResult.getData()==null || searchApiResult.getCode()!=200){
  104 + return searchApiResult;
  105 + }
  106 + //2、参数判断
  107 + JSONObject data = (JSONObject)searchApiResult.getData();
  108 + JSONArray productListJSONArray = data.getJSONArray("product_list");
  109 + if(productListJSONArray==null || productListJSONArray.isEmpty()){
  110 + data.put("page", 1);
  111 + data.put("page_size", viewNum);
  112 + data.put("total", 0);
  113 + data.put("page_total", 0);
  114 + data.put("product_list", new ArrayList<>());
  115 + return searchApiResult;
  116 + }
  117 + //3、截取productList
  118 + List<JSONObject> productList = new ArrayList<>();
  119 + for (int i =0;i<productListJSONArray.size();i++){
  120 + if(productList.size()>=viewNum){
  121 + break;
  122 + }
  123 + productList.add(productListJSONArray.getJSONObject(i));
  124 + }
  125 + //4、保留偶数
  126 + if (productList.size() % 2 > 0) {
  127 + productList = CollectionUtils.safeSubList(productList, 0, productList.size() - 1);
  128 + }
  129 + //5、构造返回结果
  130 + data.put("page", 1);
  131 + data.put("page_size", viewNum);
  132 + data.put("total", productList.size());
  133 + data.put("page_total", 1);
  134 + data.put("product_list", productList);
  135 + return searchApiResult;
  136 + }
  137 +
  138 + /**
94 * 获取SKN在ES中的原生信息 139 * 获取SKN在ES中的原生信息
95 * 140 *
96 * @param productSkn 141 * @param productSkn
@@ -50,7 +50,7 @@ public class SearchLikeInShopService { @@ -50,7 +50,7 @@ public class SearchLikeInShopService {
50 * @param paramMap 50 * @param paramMap
51 * @return 51 * @return
52 */ 52 */
53 - @SearchCacheAble(cacheInMinute = 600, cacheName = "SEARCH_LIKE_IN_SHOP", includeParams = { "product_skn", "viewNum" }) 53 + @SearchCacheAble(cacheInMinute = 600, cacheName = "SEARCH_LIKE_IN_SHOP", includeParams = { "product_skn"})
54 public SearchApiResult searchLikeInShop(Map<String, String> paramMap) { 54 public SearchApiResult searchLikeInShop(Map<String, String> paramMap) {
55 try { 55 try {
56 // 1、获取参数 56 // 1、获取参数
@@ -58,8 +58,8 @@ public class SearchLikeInShopService { @@ -58,8 +58,8 @@ public class SearchLikeInShopService {
58 if (StringUtils.isBlank(productSkn)) { 58 if (StringUtils.isBlank(productSkn)) {
59 return new SearchApiResult().setCode(400).setMessage("请输入SKN"); 59 return new SearchApiResult().setCode(400).setMessage("请输入SKN");
60 } 60 }
61 - // 2、检测分页参数【默认30条,最多60条】  
62 - int pageSize = searchLikeHelper.getPageSize(paramMap); 61 + // 2、检测分页参数【默认30条】
  62 + int viewNum = 30;
63 63
64 // 3、获取当前查询的SKN的基本信息 64 // 3、获取当前查询的SKN的基本信息
65 JSONObject productInfoInEs = searchLikeHelper.getProductInfoInEs(productSkn); 65 JSONObject productInfoInEs = searchLikeHelper.getProductInfoInEs(productSkn);
@@ -69,12 +69,12 @@ public class SearchLikeInShopService { @@ -69,12 +69,12 @@ public class SearchLikeInShopService {
69 69
70 // 4、设置SearchParams 70 // 4、设置SearchParams
71 List<SearchParam> searchParams = new ArrayList<SearchParam>(); 71 List<SearchParam> searchParams = new ArrayList<SearchParam>();
72 - searchParams.add(this.builderSearchParam(productInfoInEs, Arrays.asList(productSkn), pageSize)); 72 + searchParams.add(this.builderSearchParam(productInfoInEs, Arrays.asList(productSkn), viewNum));
73 73
74 // 5、获取搜索结果[截取条数] 74 // 5、获取搜索结果[截取条数]
75 List<Map<String, Object>> tempProductList = searchLikeHelper.queryProductList(searchParams); 75 List<Map<String, Object>> tempProductList = searchLikeHelper.queryProductList(searchParams);
76 - if (tempProductList.size() > pageSize) {  
77 - tempProductList = CollectionUtils.safeSubList(tempProductList,0, pageSize); 76 + if (tempProductList.size() > viewNum) {
  77 + tempProductList = CollectionUtils.safeSubList(tempProductList,0, viewNum);
78 } 78 }
79 79
80 // 6、构造真实返回结果 80 // 6、构造真实返回结果
@@ -83,10 +83,6 @@ public class SearchLikeInShopService { @@ -83,10 +83,6 @@ public class SearchLikeInShopService {
83 productListResults = productListHelper.buildReturnInfoByEsSourceList(tempProductList); 83 productListResults = productListHelper.buildReturnInfoByEsSourceList(tempProductList);
84 } 84 }
85 JSONObject result = new JSONObject(); 85 JSONObject result = new JSONObject();
86 - result.put("page", 1);  
87 - result.put("page_total", 1);  
88 - result.put("page_size", pageSize);  
89 - result.put("total", productListResults.size());  
90 result.put("product_info", searchLikeHelper.genProductInfoResult(productInfoInEs)); 86 result.put("product_info", searchLikeHelper.genProductInfoResult(productInfoInEs));
91 result.put("product_list", productListResults); 87 result.put("product_list", productListResults);
92 return new SearchApiResult().setData(result); 88 return new SearchApiResult().setData(result);