Authored by Gino Zhang

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

  1 +package com.yoho.search.service.restapi;
  2 +
  3 +import java.util.Map;
  4 +
  5 +import javax.servlet.http.HttpServletRequest;
  6 +
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.stereotype.Controller;
  9 +import org.springframework.web.bind.annotation.ModelAttribute;
  10 +import org.springframework.web.bind.annotation.RequestMapping;
  11 +import org.springframework.web.bind.annotation.RequestMethod;
  12 +import org.springframework.web.bind.annotation.ResponseBody;
  13 +
  14 +import com.yoho.search.service.downgrade.aop.DownGradeAble;
  15 +import com.yoho.search.service.servicenew.IBreakSizeService;
  16 +import com.yoho.search.service.utils.HttpServletRequestUtils;
  17 +import com.yoho.search.service.vo.SearchApiResult;
  18 +import com.yoho.search.service.vo.SizeSortReqBO;
  19 +
  20 +@Controller
  21 +public class BreakSizeController {
  22 +
  23 + @Autowired
  24 + private IBreakSizeService breakSizeService;
  25 +
  26 + /**
  27 + * 【断码区】获取分类,以及分类下的型号列表(with storage_sku)
  28 + *
  29 + * @return
  30 + */
  31 + @DownGradeAble(key = "sort_sizes")
  32 + @RequestMapping(method = RequestMethod.GET, value = "/sort_sizes")
  33 + @ResponseBody
  34 + public SearchApiResult sort_sizes(@ModelAttribute SizeSortReqBO sizeSortReqBO) {
  35 + return breakSizeService.sortSizes(sizeSortReqBO);
  36 + }
  37 +
  38 + /**
  39 + * 【断码区】按分类和型号获取商品(with storage_sku)
  40 + *
  41 + * @param request
  42 + * @return
  43 + */
  44 + @DownGradeAble(key = "sort_size_products")
  45 + @RequestMapping(method = RequestMethod.GET, value = "/sort_size_products")
  46 + @ResponseBody
  47 + public SearchApiResult sort_size_products(HttpServletRequest request) {
  48 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  49 + return breakSizeService.sort_size_products(paramMap);
  50 + }
  51 +
  52 +}
  1 +package com.yoho.search.service.restapi;
  2 +
  3 +import java.util.Map;
  4 +
  5 +import javax.servlet.http.HttpServletRequest;
  6 +
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.stereotype.Controller;
  9 +import org.springframework.web.bind.annotation.RequestMapping;
  10 +import org.springframework.web.bind.annotation.RequestMethod;
  11 +import org.springframework.web.bind.annotation.ResponseBody;
  12 +
  13 +import com.yoho.search.service.servicenew.IProductListService;
  14 +import com.yoho.search.service.utils.HttpServletRequestUtils;
  15 +import com.yoho.search.service.vo.SearchApiResult;
  16 +
  17 +@Controller
  18 +public class ProductListController {
  19 +
  20 + @Autowired
  21 + private IProductListService productListService;
  22 +
  23 + /**
  24 + * 获取商品列表
  25 + *
  26 + * @return
  27 + */
  28 + @RequestMapping(method = RequestMethod.GET, value = "/productindex/productList")
  29 + @ResponseBody
  30 + public SearchApiResult productList(HttpServletRequest request) {
  31 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  32 + return productListService.productList(paramMap);
  33 + }
  34 +
  35 + /**
  36 + * 打印获取商品列表的ES的dsl的工具接口
  37 + *
  38 + * @return
  39 + */
  40 + @RequestMapping(method = RequestMethod.GET, value = "/dsl/productList")
  41 + @ResponseBody
  42 + public SearchApiResult getESDsl(HttpServletRequest request) {
  43 + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
  44 + return productListService.getESDsl(paramMap);
  45 + }
  46 +
  47 +}
1 package com.yoho.search.service.restapi; 1 package com.yoho.search.service.restapi;
2 2
3 -import com.yoho.search.service.downgrade.aop.DownGradeAble;  
4 -import com.yoho.search.service.service.SearchSortSizeService;  
5 -import com.yoho.search.service.servicenew.*;  
6 -import com.yoho.search.service.servicenew.impl.SearchSortGroupService;  
7 -import com.yoho.search.service.utils.HttpServletRequestUtils;  
8 -import com.yoho.search.service.vo.SearchApiResult;  
9 -import com.yoho.search.service.vo.SizeSortReqBO;  
10 -import com.yoho.search.service.vo.SuggestApiResult; 3 +import java.util.Map;
  4 +
  5 +import javax.servlet.http.HttpServletRequest;
  6 +
11 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.beans.factory.annotation.Autowired;
12 import org.springframework.stereotype.Controller; 8 import org.springframework.stereotype.Controller;
13 -import org.springframework.web.bind.annotation.ModelAttribute;  
14 import org.springframework.web.bind.annotation.RequestMapping; 9 import org.springframework.web.bind.annotation.RequestMapping;
15 import org.springframework.web.bind.annotation.RequestMethod; 10 import org.springframework.web.bind.annotation.RequestMethod;
16 import org.springframework.web.bind.annotation.ResponseBody; 11 import org.springframework.web.bind.annotation.ResponseBody;
17 12
18 -import javax.servlet.http.HttpServletRequest;  
19 -import java.util.Map; 13 +import com.yoho.search.service.downgrade.aop.DownGradeAble;
  14 +import com.yoho.search.service.service.SearchSortSizeService;
  15 +import com.yoho.search.service.servicenew.IProductIndexService;
  16 +import com.yoho.search.service.servicenew.ISearchWithCacheService;
  17 +import com.yoho.search.service.servicenew.ISearchWithLocalCacheService;
  18 +import com.yoho.search.service.servicenew.ISelectionsWithAdvanceService;
  19 +import com.yoho.search.service.servicenew.ISelectionsWithOutAdvanceService;
  20 +import com.yoho.search.service.servicenew.impl.SearchSortGroupService;
  21 +import com.yoho.search.service.utils.HttpServletRequestUtils;
  22 +import com.yoho.search.service.vo.SearchApiResult;
  23 +import com.yoho.search.service.vo.SuggestApiResult;
20 24
21 @Controller 25 @Controller
22 public class SearchNewController { 26 public class SearchNewController {
@@ -107,20 +111,6 @@ public class SearchNewController { @@ -107,20 +111,6 @@ public class SearchNewController {
107 } 111 }
108 112
109 /** 113 /**
110 - * 按分类和型号获取商品(with storage_sku)  
111 - *  
112 - * @param request  
113 - * @return  
114 - */  
115 - @DownGradeAble(key = "sort_size_products")  
116 - @RequestMapping(method = RequestMethod.GET, value = "/sort_size_products")  
117 - @ResponseBody  
118 - public SearchApiResult sort_size_products(HttpServletRequest request) {  
119 - Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);  
120 - return searchWithLocalCacheService.sort_size_products(paramMap);  
121 - }  
122 -  
123 - /**  
124 * 批量获取brandIds对应的商品数量和商品列表[我收藏的品牌] 114 * 批量获取brandIds对应的商品数量和商品列表[我收藏的品牌]
125 * 115 *
126 * @param request 116 * @param request
@@ -227,18 +217,6 @@ public class SearchNewController { @@ -227,18 +217,6 @@ public class SearchNewController {
227 } 217 }
228 218
229 /** 219 /**
230 - * 获取分类,以及分类下的型号列表(with storage_sku)  
231 - *  
232 - * @return  
233 - */  
234 - @DownGradeAble(key = "sort_sizes")  
235 - @RequestMapping(method = RequestMethod.GET, value = "/sort_sizes")  
236 - @ResponseBody  
237 - public SearchApiResult sort_sizes(@ModelAttribute SizeSortReqBO sizeSortReqBO) {  
238 - return searchWithCacheService.sortSizes(sizeSortReqBO);  
239 - }  
240 -  
241 - /**  
242 * 按品牌前缀名获取品牌列表 220 * 按品牌前缀名获取品牌列表
243 * 221 *
244 * @param request 222 * @param request
@@ -267,33 +245,6 @@ public class SearchNewController { @@ -267,33 +245,6 @@ public class SearchNewController {
267 } 245 }
268 246
269 247
270 -  
271 -  
272 - /**  
273 - * 获取商品列表  
274 - *  
275 - * @return  
276 - */  
277 - //@DownGradeAble(key = "productList")  
278 - @RequestMapping(method = RequestMethod.GET, value = "/productindex/productList")  
279 - @ResponseBody  
280 - public SearchApiResult productList(HttpServletRequest request) {  
281 - Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);  
282 - return searchWithLocalCacheService.productList(paramMap);  
283 - }  
284 -  
285 - /**  
286 - * 打印获取商品列表的ES的dsl的工具接口  
287 - *  
288 - * @return  
289 - */  
290 - @RequestMapping(method = RequestMethod.GET, value = "/dsl/productList")  
291 - @ResponseBody  
292 - public SearchApiResult getESDsl(HttpServletRequest request) {  
293 - Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);  
294 - return searchWithLocalCacheService.getESDsl(paramMap);  
295 - }  
296 -  
297 /** 248 /**
298 * 聚合品牌 249 * 聚合品牌
299 * 250 *
@@ -60,7 +60,8 @@ public class SearchCommonService implements ApplicationEventPublisherAware { @@ -60,7 +60,8 @@ public class SearchCommonService implements ApplicationEventPublisherAware {
60 */ 60 */
61 public SearchResult doSearch(final String indexName, final SearchParam searchParam) { 61 public SearchResult doSearch(final String indexName, final SearchParam searchParam) {
62 // TODO: need be tested 62 // TODO: need be tested
63 - // SearchResult searchResult = yohoIndexService.search(indexName, searchParam); 63 + // SearchResult searchResult = yohoIndexService.search(indexName,
  64 + // searchParam);
64 IElasticsearchClient client = esClientMgr.getClient(indexName); 65 IElasticsearchClient client = esClientMgr.getClient(indexName);
65 SearchResult searchResult = client.search(indexName, indexName, searchParam); 66 SearchResult searchResult = client.search(indexName, indexName, searchParam);
66 this.publishSearchResultEvent(indexName, searchParam, searchResult); 67 this.publishSearchResultEvent(indexName, searchParam, searchResult);
@@ -68,6 +69,19 @@ public class SearchCommonService implements ApplicationEventPublisherAware { @@ -68,6 +69,19 @@ public class SearchCommonService implements ApplicationEventPublisherAware {
68 } 69 }
69 70
70 /** 71 /**
  72 + * 根据多个索引查询
  73 + * @param indexNames
  74 + * @param searchParam
  75 + * @return
  76 + */
  77 + public SearchResult doSearch(final List<String> indexNames, final SearchParam searchParam) {
  78 + IElasticsearchClient client = esClientMgr.getClient(indexNames.get(0));
  79 + SearchResult searchResult = client.search(indexNames, indexNames, searchParam);
  80 + this.publishSearchResultEvent(indexNames.toString(), searchParam, searchResult);
  81 + return searchResult;
  82 + }
  83 +
  84 + /**
71 * 通用的查询接口 85 * 通用的查询接口
72 * 86 *
73 * @param indexName 87 * @param indexName
@@ -80,7 +94,8 @@ public class SearchCommonService implements ApplicationEventPublisherAware { @@ -80,7 +94,8 @@ public class SearchCommonService implements ApplicationEventPublisherAware {
80 } 94 }
81 95
82 // TODO: need be tested 96 // TODO: need be tested
83 - // List<SearchResult> results = yohoIndexService.multiSearch(indexName, searchParams); 97 + // List<SearchResult> results = yohoIndexService.multiSearch(indexName,
  98 + // searchParams);
84 IElasticsearchClient client = esClientMgr.getClient(indexName); 99 IElasticsearchClient client = esClientMgr.getClient(indexName);
85 List<SearchResult> results = client.multiSearch(indexName, indexName, searchParams); 100 List<SearchResult> results = client.multiSearch(indexName, indexName, searchParams);
86 for (int i = 0; i < searchParams.size(); i++) { 101 for (int i = 0; i < searchParams.size(); i++) {
@@ -157,7 +172,7 @@ public class SearchCommonService implements ApplicationEventPublisherAware { @@ -157,7 +172,7 @@ public class SearchCommonService implements ApplicationEventPublisherAware {
157 return new JSONArray(); 172 return new JSONArray();
158 } 173 }
159 } 174 }
160 - 175 +
161 /** 176 /**
162 * 通过id获取内容 177 * 通过id获取内容
163 * 178 *
@@ -172,16 +187,17 @@ public class SearchCommonService implements ApplicationEventPublisherAware { @@ -172,16 +187,17 @@ public class SearchCommonService implements ApplicationEventPublisherAware {
172 } 187 }
173 188
174 // TODO: need be tested 189 // TODO: need be tested
175 - // MultiGetResponse response = yohoIndexService.multiGet(indexName, idSet, fields); 190 + // MultiGetResponse response = yohoIndexService.multiGet(indexName,
  191 + // idSet, fields);
176 IElasticsearchClient client = esClientMgr.getClient(indexName); 192 IElasticsearchClient client = esClientMgr.getClient(indexName);
177 String realIndexName = yohoIndexHelper.getRealIndexName(indexName, client); 193 String realIndexName = yohoIndexHelper.getRealIndexName(indexName, client);
178 if (StringUtils.isBlank(realIndexName)) { 194 if (StringUtils.isBlank(realIndexName)) {
179 return null; 195 return null;
180 } 196 }
181 - MultiGetResponse response = client.multiGet(realIndexName, indexName, idSet, fields); 197 + MultiGetResponse response = client.multiGet(realIndexName, indexName, idSet, fields);
182 return makeResponse(response, indexName); 198 return makeResponse(response, indexName);
183 } 199 }
184 - 200 +
185 private JSONArray makeResponse(final MultiGetResponse response, final String indexName) { 201 private JSONArray makeResponse(final MultiGetResponse response, final String indexName) {
186 // 构造返回结果 202 // 构造返回结果
187 JSONArray list = new JSONArray(); 203 JSONArray list = new JSONArray();
@@ -12,6 +12,7 @@ import java.util.Map; @@ -12,6 +12,7 @@ import java.util.Map;
12 12
13 import javax.annotation.PostConstruct; 13 import javax.annotation.PostConstruct;
14 14
  15 +import org.apache.commons.collections.CollectionUtils;
15 import org.apache.commons.lang.StringUtils; 16 import org.apache.commons.lang.StringUtils;
16 import org.elasticsearch.index.query.BoolQueryBuilder; 17 import org.elasticsearch.index.query.BoolQueryBuilder;
17 import org.elasticsearch.index.query.MatchQueryBuilder; 18 import org.elasticsearch.index.query.MatchQueryBuilder;
@@ -38,20 +39,6 @@ import com.yoho.search.service.personalized.PersonalizedSearch; @@ -38,20 +39,6 @@ import com.yoho.search.service.personalized.PersonalizedSearch;
38 import com.yoho.search.service.personalized.model.SearchFeature; 39 import com.yoho.search.service.personalized.model.SearchFeature;
39 import com.yoho.search.service.utils.HttpServletRequestUtils; 40 import com.yoho.search.service.utils.HttpServletRequestUtils;
40 import com.yoho.search.service.utils.SearchRequestParams; 41 import com.yoho.search.service.utils.SearchRequestParams;
41 -import org.apache.commons.collections.CollectionUtils;  
42 -import org.apache.commons.lang.StringUtils;  
43 -import org.elasticsearch.index.query.*;  
44 -import org.elasticsearch.search.sort.FieldSortBuilder;  
45 -import org.elasticsearch.search.sort.SortBuilder;  
46 -import org.elasticsearch.search.sort.SortBuilders;  
47 -import org.elasticsearch.search.sort.SortOrder;  
48 -import org.slf4j.Logger;  
49 -import org.slf4j.LoggerFactory;  
50 -import org.springframework.beans.factory.annotation.Autowired;  
51 -import org.springframework.stereotype.Service;  
52 -  
53 -import javax.annotation.PostConstruct;  
54 -import java.util.*;  
55 42
56 @Service 43 @Service
57 public class SearchServiceHelper { 44 public class SearchServiceHelper {
  1 +package com.yoho.search.service.servicenew;
  2 +
  3 +import java.util.Map;
  4 +
  5 +import com.yoho.search.service.vo.SearchApiResult;
  6 +import com.yoho.search.service.vo.SizeSortReqBO;
  7 +
  8 +public interface IBreakSizeService {
  9 +
  10 + /**
  11 + * 获取断码区的品类和尺码信息
  12 + *
  13 + * @param sizeSortReqBO
  14 + * @return
  15 + */
  16 + public SearchApiResult sortSizes(SizeSortReqBO sizeSortReqBO);
  17 +
  18 + /**
  19 + * 获取断码区的商品列表【支持聚合】[使用本地缓存]
  20 + *
  21 + * @param paramMap
  22 + * @return
  23 + */
  24 + public SearchApiResult sort_size_products(Map<String, String> paramMap);
  25 +
  26 +}
  1 +package com.yoho.search.service.servicenew;
  2 +
  3 +import java.util.Map;
  4 +
  5 +import com.yoho.search.service.vo.SearchApiResult;
  6 +
  7 +public interface IProductListService {
  8 +
  9 + /**
  10 + * 获取商品列表[使用本地缓存]
  11 + * @param paramMap
  12 + * @return
  13 + */
  14 + public SearchApiResult productList(Map<String, String> paramMap);
  15 +
  16 + /**
  17 + * 打印获取商品列表的ES语句
  18 + * @param paramMap
  19 + * @return
  20 + */
  21 + public SearchApiResult getESDsl(Map<String, String> paramMap);
  22 +
  23 +}
1 package com.yoho.search.service.servicenew; 1 package com.yoho.search.service.servicenew;
2 2
  3 +import java.util.Map;
  4 +
3 import com.yoho.search.service.vo.SearchApiResult; 5 import com.yoho.search.service.vo.SearchApiResult;
4 -import com.yoho.search.service.vo.SizeSortReqBO;  
5 import com.yoho.search.service.vo.SuggestApiResult; 6 import com.yoho.search.service.vo.SuggestApiResult;
6 7
7 -import java.util.Map;  
8 -  
9 public interface ISearchWithCacheService { 8 public interface ISearchWithCacheService {
10 9
11 /** 10 /**
@@ -41,15 +40,6 @@ public interface ISearchWithCacheService { @@ -41,15 +40,6 @@ public interface ISearchWithCacheService {
41 public SearchApiResult aggProductsByBrandIdInParam(Map<String, String> paramMap); 40 public SearchApiResult aggProductsByBrandIdInParam(Map<String, String> paramMap);
42 41
43 /** 42 /**
44 - * 获取断码区的品类和尺码信息  
45 - *  
46 - * @param sizeSortReqBO  
47 - * @return  
48 - */  
49 - public SearchApiResult sortSizes(SizeSortReqBO sizeSortReqBO);  
50 -  
51 -  
52 - /**  
53 * 获取某个品牌下面的商品【我收藏的品牌】 43 * 获取某个品牌下面的商品【我收藏的品牌】
54 * 44 *
55 * @param paramMap 45 * @param paramMap
1 package com.yoho.search.service.servicenew; 1 package com.yoho.search.service.servicenew;
2 2
3 -import com.yoho.search.service.vo.SearchApiResult;  
4 -  
5 import java.util.Map; 3 import java.util.Map;
6 4
  5 +import com.yoho.search.service.vo.SearchApiResult;
  6 +
7 /** 7 /**
8 * 使用本地缓存的接口,因为数据量比较大 8 * 使用本地缓存的接口,因为数据量比较大
  9 + *
9 * @author hugufei 10 * @author hugufei
10 * 11 *
11 */ 12 */
12 public interface ISearchWithLocalCacheService { 13 public interface ISearchWithLocalCacheService {
13 -  
14 - /**  
15 - * 获取商品列表[使用本地缓存]  
16 - * @param paramMap  
17 - * @return  
18 - */  
19 - public SearchApiResult productList(Map<String, String> paramMap);  
20 14
21 /** 15 /**
22 - * 打印获取商品列表的ES语句  
23 - * @param paramMap  
24 - * @return  
25 - */  
26 - public SearchApiResult getESDsl(Map<String, String> paramMap);  
27 -  
28 - /**  
29 * 获取品牌的聚合结果[使用本地缓存] 16 * 获取品牌的聚合结果[使用本地缓存]
  17 + *
30 * @param paramMap 18 * @param paramMap
31 * @return 19 * @return
32 */ 20 */
33 public SearchApiResult aggBrand(Map<String, String> paramMap); 21 public SearchApiResult aggBrand(Map<String, String> paramMap);
34 - 22 +
35 /** 23 /**
36 * 按品牌前缀名获取品牌列表[使用本地缓存] 24 * 按品牌前缀名获取品牌列表[使用本地缓存]
  25 + *
37 * @param paramMap 26 * @param paramMap
38 * @return 27 * @return
39 */ 28 */
40 public SearchApiResult brands(Map<String, String> paramMap); 29 public SearchApiResult brands(Map<String, String> paramMap);
41 - 30 +
42 /** 31 /**
43 * 获取商品列表[直接从brand索引里取全部] 32 * 获取商品列表[直接从brand索引里取全部]
  33 + *
44 * @param paramMap 34 * @param paramMap
45 * @return 35 * @return
46 */ 36 */
47 public SearchApiResult brandList(Map<String, String> paramMap); 37 public SearchApiResult brandList(Map<String, String> paramMap);
48 -  
49 - /**  
50 - * 获取断码区的商品列表【支持聚合】[使用本地缓存]  
51 - * @param paramMap  
52 - * @return  
53 - */  
54 - public SearchApiResult sort_size_products(Map<String, String> paramMap);  
55 - 38 +
56 /** 39 /**
57 * 获取商品池列表 40 * 获取商品池列表
  41 + *
58 * @param paramMap 42 * @param paramMap
59 * @return 43 * @return
60 */ 44 */
61 public SearchApiResult productPool(Map<String, String> paramMap); 45 public SearchApiResult productPool(Map<String, String> paramMap);
62 46
63 -  
64 -  
65 -  
66 } 47 }
  1 +package com.yoho.search.service.servicenew.impl;
  2 +
  3 +import java.util.Map;
  4 +
  5 +import org.slf4j.Logger;
  6 +import org.slf4j.LoggerFactory;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.stereotype.Service;
  9 +
  10 +import com.alibaba.fastjson.JSONArray;
  11 +import com.alibaba.fastjson.JSONObject;
  12 +import com.yoho.search.service.service.SearchSortSizeService;
  13 +import com.yoho.search.service.servicenew.IBreakSizeService;
  14 +import com.yoho.search.service.servicenew.IProductIndexService;
  15 +import com.yoho.search.service.servicenew.IProductListService;
  16 +import com.yoho.search.service.servicenew.ISelectionsWithAdvanceService;
  17 +import com.yoho.search.service.utils.SearchApiResultUtils;
  18 +import com.yoho.search.service.utils.SearchRequestParams;
  19 +import com.yoho.search.service.utils.StringSplitUtils;
  20 +import com.yoho.search.service.vo.SearchApiResult;
  21 +import com.yoho.search.service.vo.SizeSortReqBO;
  22 +
  23 +@Service
  24 +public class BreakSizeServiceImpl implements IBreakSizeService {
  25 +
  26 + private static final Logger logger = LoggerFactory.getLogger(SearchWithLocalCacheServiceImpl.class);
  27 +
  28 + @Autowired
  29 + private SearchSortSizeService searchSortSizeService;
  30 + @Autowired
  31 + private IProductListService productListService;
  32 + @Autowired
  33 + private IProductIndexService productIndexService;
  34 + @Autowired
  35 + private ISelectionsWithAdvanceService selectionsWithAdvanceService;
  36 +
  37 + @Override
  38 + public SearchApiResult sortSizes(SizeSortReqBO sizeSortReqBO) {
  39 + return searchSortSizeService.sortSizes(sizeSortReqBO);
  40 + }
  41 +
  42 + @Override
  43 + public SearchApiResult sort_size_products(Map<String, String> paramMap) {
  44 + try {
  45 + logger.info("[func=sort_size_products][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());
  46 + // 1、先判断参数是否需要聚合【聚合不走storageSku索引】
  47 + JSONObject filter = new JSONObject();
  48 + if (paramMap.containsKey("needFilter") && "1".equals(paramMap.get("needFilter"))) {
  49 + // 1)获取不带全部品牌的聚合结果
  50 + paramMap.put("aggStorageSku", "aggStorageSku");
  51 + SearchApiResult filterResult = selectionsWithAdvanceService.getSelectionsWithAdvance(paramMap);
  52 + JSONObject filterJSONObject = this.getFilterResultFromJSONObject(filterResult);
  53 + if (filterJSONObject != null) {
  54 + filter = filterJSONObject;
  55 + }
  56 + // 2)获取品牌的聚合结果
  57 + SearchApiResult aggBrandResult = productIndexService.aggBrand(paramMap);
  58 + JSONArray aggBrand = this.getAggBrandResultFromJSONObject(aggBrandResult);
  59 + if (aggBrand != null && !aggBrand.isEmpty()) {
  60 + filter.put("brand", aggBrand);
  61 + }
  62 + }
  63 + // 2、从storageSku索引里根据参数获取skn[已使用本地缓存]
  64 + JSONObject productData = new JSONObject();
  65 + String[] productSkns = searchSortSizeService.getProductSknFromStorageSkuIndex(paramMap, 200);
  66 + if (productSkns == null || productSkns.length == 0) {
  67 + productData.put("total", 0);
  68 + productData.put("page_total", 0);
  69 + productData.put("page", 1);
  70 + productData.put("product_list", new JSONArray());
  71 + } else {
  72 + // 根据skn和其他参数查询结果[已使用本地缓存]
  73 + String productSknStr = StringSplitUtils.collectionToString(productSkns, ",");
  74 + paramMap.put(SearchRequestParams.PARAM_SYNC_SKN, productSknStr);
  75 + SearchApiResult searchApiResult = productListService.productList(paramMap);
  76 + productData = getProductResultFromJSONObject(searchApiResult);
  77 + }
  78 +
  79 + // 3、拼装真正的结果
  80 + JSONObject realData = new JSONObject();
  81 + if (filter != null && !filter.isEmpty()) {
  82 + realData.put("filter", filter);
  83 + }
  84 + if (productData != null) {
  85 + realData.putAll(productData);
  86 + }
  87 + return new SearchApiResult().setData(realData);
  88 + } catch (Exception e) {
  89 + return SearchApiResultUtils.errorSearchApiResult("sort_size_products", paramMap, e);
  90 + }
  91 + }
  92 +
  93 + private JSONObject getFilterResultFromJSONObject(SearchApiResult aggResult) {
  94 + try {
  95 + if (aggResult == null) {
  96 + return null;
  97 + }
  98 + JSONObject data = (JSONObject) aggResult.getData();
  99 + return data.getJSONObject("filter");
  100 + } catch (Exception e) {
  101 + logger.error(e.getMessage(), e);
  102 + return null;
  103 + }
  104 + }
  105 +
  106 + private JSONArray getAggBrandResultFromJSONObject(SearchApiResult aggBrandResult) {
  107 + try {
  108 + if (aggBrandResult == null) {
  109 + return null;
  110 + }
  111 + return (JSONArray) aggBrandResult.getData();
  112 + } catch (Exception e) {
  113 + logger.error(e.getMessage(), e);
  114 + return null;
  115 + }
  116 + }
  117 +
  118 + private JSONObject getProductResultFromJSONObject(SearchApiResult aggResult) {
  119 + try {
  120 + if (aggResult == null) {
  121 + return null;
  122 + }
  123 + return (JSONObject) aggResult.getData();
  124 + } catch (Exception e) {
  125 + logger.error(e.getMessage(), e);
  126 + return null;
  127 + }
  128 + }
  129 +
  130 +}
  1 +package com.yoho.search.service.servicenew.impl;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.Arrays;
  5 +import java.util.List;
  6 +import java.util.Map;
  7 +
  8 +import org.apache.commons.lang.StringUtils;
  9 +import org.elasticsearch.search.builder.SearchSourceBuilder;
  10 +import org.slf4j.Logger;
  11 +import org.slf4j.LoggerFactory;
  12 +import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.stereotype.Service;
  14 +
  15 +import com.alibaba.fastjson.JSONObject;
  16 +import com.yoho.search.base.utils.ISearchConstants;
  17 +import com.yoho.search.core.es.model.SearchParam;
  18 +import com.yoho.search.core.es.model.SearchResult;
  19 +import com.yoho.search.core.es.utils.SearchParamUtils;
  20 +import com.yoho.search.service.aggregations.impls.AggregationFactoryService;
  21 +import com.yoho.search.service.cache.CacheEnum;
  22 +import com.yoho.search.service.cache.LocalCacheService;
  23 +import com.yoho.search.service.service.AggregationService;
  24 +import com.yoho.search.service.service.SearchCacheService;
  25 +import com.yoho.search.service.service.SearchCommonService;
  26 +import com.yoho.search.service.service.SearchKeyWordService;
  27 +import com.yoho.search.service.service.SearchServiceHelper;
  28 +import com.yoho.search.service.service.SearchSortSizeService;
  29 +import com.yoho.search.service.servicenew.IProductIndexService;
  30 +import com.yoho.search.service.servicenew.IProductListService;
  31 +import com.yoho.search.service.servicenew.ISelectionsWithAdvanceService;
  32 +import com.yoho.search.service.utils.HttpServletRequestUtils;
  33 +import com.yoho.search.service.utils.SearchApiResultUtils;
  34 +import com.yoho.search.service.vo.SearchApiResult;
  35 +
  36 +@Service
  37 +public class ProductListServiceImpl implements IProductListService {
  38 +
  39 + private static final Logger logger = LoggerFactory.getLogger(ProductListServiceImpl.class);
  40 + private static Logger CACHE_MATCH_REQUEST = LoggerFactory.getLogger("CACHE_MATCH_REQUEST");
  41 +
  42 + @Autowired
  43 + private SearchServiceHelper searchServiceHelper;
  44 + @Autowired
  45 + private AggregationFactoryService aggregationFactoryService;
  46 + @Autowired
  47 + private AggregationService aggregationService;
  48 + @Autowired
  49 + private SearchCommonService searchCommonService;
  50 + @Autowired
  51 + private SearchAfterCacheService searchAfterCacheService;
  52 + @Autowired
  53 + private SearchSortSizeService searchSortSizeService;
  54 + @Autowired
  55 + private IProductIndexService productIndexService;
  56 + @Autowired
  57 + private LocalCacheService localCacheService;
  58 + @Autowired
  59 + private ISelectionsWithAdvanceService selectionsWithAdvanceService;
  60 + @Autowired
  61 + private SearchKeyWordService searchKeyWordService;
  62 + @Autowired
  63 + private SearchCacheService searchCacheService;
  64 +
  65 + @Override
  66 + public SearchApiResult productList(Map<String, String> paramMap) {
  67 + try {
  68 + logger.info("[func=productList][param={}][begin={}]", paramMap, System.currentTimeMillis());
  69 +
  70 + // 1)构造搜索参数
  71 + SearchParam searchParam = buildProductListSearchParam(paramMap);
  72 +
  73 + // 5)从缓存中获取数据
  74 + final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
  75 + CacheEnum cacheEnum = CacheEnum.EHCACHE;
  76 + JSONObject cacheObject = searchCacheService.getJSONObjectFromCache(cacheEnum, indexName, searchParam);
  77 + if (cacheObject != null) {
  78 + CACHE_MATCH_REQUEST.info("match cache , url is :/productindex/productList.json?" + HttpServletRequestUtils.genParamString(paramMap));
  79 + return new SearchApiResult().setData(cacheObject);
  80 + }
  81 +
  82 + // 6)查询ES
  83 + SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
  84 + if (searchResult == null) {
  85 + return new SearchApiResult().setCode(500).setMessage("execption");
  86 + }
  87 + // 7)记录关键字对应的查询结果
  88 + String queryWord = paramMap.get("query");
  89 + if (!StringUtils.isBlank(queryWord) && !searchServiceHelper.isQuerySkn(queryWord)) {
  90 + searchKeyWordService.recordKeyWordByResultCount(queryWord, searchResult.getTotal());
  91 + }
  92 + // 8)当返回结果为空时,先记录请求参数,然后修改operator为or并重新搜索,minimum修改为50%
  93 + if (StringUtils.isNotBlank(queryWord) && 0 == searchResult.getTotal()) {
  94 + searchKeyWordService.handleEmptyRecords(paramMap);
  95 + logger.info("search result is empty by operator of AND, will use operator of OR to reenforce search result");
  96 + searchParam.setQuery(searchServiceHelper.constructOrQueryBuilder(paramMap));
  97 + searchResult = searchCommonService.doSearch(indexName, searchParam);
  98 + }
  99 +
  100 + // 9)构造返回结果
  101 + JSONObject dataMap = new JSONObject();
  102 + dataMap.put("total", searchResult.getTotal());
  103 + dataMap.put("page", searchResult.getPage());
  104 + dataMap.put("page_size", searchParam.getSize());
  105 + dataMap.put("page_total", searchResult.getTotalPage());
  106 + dataMap.put("product_list", searchServiceHelper.getProductMapList(searchResult.getResultList()));
  107 +
  108 + // 10)将结果存进缓存
  109 + searchCacheService.addJSONObjectToCache(cacheEnum, indexName, searchParam, dataMap);
  110 + return new SearchApiResult().setData(dataMap);
  111 + } catch (Exception e) {
  112 + return SearchApiResultUtils.errorSearchApiResult("productList", paramMap, e);
  113 + }
  114 + }
  115 +
  116 + @Override
  117 + public SearchApiResult getESDsl(Map<String, String> paramMap) {
  118 + logger.info("[func=getESDsl][param={}]", paramMap);
  119 + try {
  120 + SearchParam searchParam = buildProductListSearchParam(paramMap);
  121 + SearchSourceBuilder searchSourceBuilder = SearchParamUtils.genSearchSourceBuilderFromSearchParam(searchParam);
  122 + SearchApiResult searchApiResult = new SearchApiResult();
  123 + searchApiResult.setData(searchSourceBuilder.toString());
  124 + logger.info("[func=getESDsl][dsl=\n{}]", searchApiResult.getData());
  125 + return searchApiResult;
  126 + } catch (Exception e) {
  127 + return SearchApiResultUtils.errorSearchApiResult("getESDsl", paramMap, e);
  128 + }
  129 + }
  130 +
  131 + private void setHighlight(final Map<String, String> paramMap, SearchParam searchParam) {
  132 + if (StringUtils.isNotBlank(paramMap.get("highlight")) && "1".equals(paramMap.get("highlight")) && StringUtils.isNotBlank(paramMap.get("query"))) {
  133 + searchParam.setHighlight(true);
  134 + List<String> highlightFields = new ArrayList<String>();
  135 + highlightFields.add("productName.productName_ansj");
  136 + searchParam.setHighlightFields(highlightFields);
  137 + }
  138 + }
  139 +
  140 + private SearchParam buildProductListSearchParam(Map<String, String> paramMap) throws Exception {
  141 + // 1)验证查询条数
  142 + int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
  143 + int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
  144 + if (page < 1 || pageSize < 0) {
  145 + throw new IllegalArgumentException("分页参数不合法");
  146 + }
  147 + if (pageSize > 500) {
  148 + pageSize = 500;
  149 + }
  150 +
  151 + // 2)构建基本查询参数
  152 + paramMap.put("isProductList", "Y");// 加个参数,表明是商品列表
  153 + SearchParam searchParam = new SearchParam();
  154 + searchParam.setQuery(searchServiceHelper.constructQueryBuilderForProductList(paramMap));
  155 + searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null));
  156 + setHighlight(paramMap, searchParam);
  157 + searchParam.setAggregationBuilders(null);
  158 + searchParam.setPage(page);
  159 + searchParam.setOffset((page - 1) * pageSize);
  160 + searchParam.setSize(pageSize);
  161 +
  162 + // 3)设置排序字段
  163 + searchParam.setSortBuilders(searchServiceHelper.buildSortList(paramMap));
  164 +
  165 + // 4)设置查询结果返回字段
  166 + if (StringUtils.isNotBlank(paramMap.get("resultFields"))) {
  167 + String resultFields = paramMap.get("resultFields");
  168 + searchParam.setResultFields(Arrays.asList(resultFields.split(",")));
  169 + }
  170 +
  171 + return searchParam;
  172 + }
  173 +
  174 +}
1 package com.yoho.search.service.servicenew.impl; 1 package com.yoho.search.service.servicenew.impl;
2 2
3 -import com.alibaba.fastjson.JSONArray;  
4 -import com.alibaba.fastjson.JSONObject;  
5 -import com.yoho.error.event.SearchEvent;  
6 -import com.yoho.search.base.utils.EventReportEnum;  
7 -import com.yoho.search.base.utils.ISearchConstants;  
8 -import com.yoho.search.core.es.agg.IAggregation;  
9 -import com.yoho.search.core.es.model.SearchParam;  
10 -import com.yoho.search.core.es.model.SearchResult;  
11 -import com.yoho.search.core.es.utils.IgnoreSomeException;  
12 -import com.yoho.search.service.aggregations.AggInterface;  
13 -import com.yoho.search.service.aggregations.impls.AggregationFactoryService;  
14 -import com.yoho.search.service.service.SearchCacheService;  
15 -import com.yoho.search.service.service.SearchCommonService;  
16 -import com.yoho.search.service.service.SearchServiceHelper;  
17 -import com.yoho.search.service.service.SearchSortSizeService;  
18 -import com.yoho.search.service.servicenew.IProductIndexService;  
19 -import com.yoho.search.service.servicenew.ISearchWithCacheService;  
20 -import com.yoho.search.service.servicenew.ISelectionsWithAdvanceService;  
21 -import com.yoho.search.service.servicenew.IShopsService;  
22 -import com.yoho.search.service.utils.HttpServletRequestUtils;  
23 -import com.yoho.search.service.utils.SearchApiResultUtils;  
24 -import com.yoho.search.service.utils.SearchRequestParams;  
25 -import com.yoho.search.service.vo.SearchApiResult;  
26 -import com.yoho.search.service.vo.SizeSortReqBO;  
27 -import com.yoho.search.service.vo.SuggestApiResult; 3 +import java.io.UnsupportedEncodingException;
  4 +import java.net.URLDecoder;
  5 +import java.util.ArrayList;
  6 +import java.util.Arrays;
  7 +import java.util.Collections;
  8 +import java.util.Comparator;
  9 +import java.util.HashMap;
  10 +import java.util.Iterator;
  11 +import java.util.List;
  12 +import java.util.Map;
  13 +import java.util.Map.Entry;
  14 +
28 import org.apache.commons.collections.CollectionUtils; 15 import org.apache.commons.collections.CollectionUtils;
29 import org.apache.commons.lang.StringUtils; 16 import org.apache.commons.lang.StringUtils;
30 -import org.elasticsearch.index.query.*; 17 +import org.elasticsearch.index.query.BoolQueryBuilder;
  18 +import org.elasticsearch.index.query.MatchQueryBuilder;
  19 +import org.elasticsearch.index.query.MultiMatchQueryBuilder;
  20 +import org.elasticsearch.index.query.QueryBuilder;
  21 +import org.elasticsearch.index.query.QueryBuilders;
  22 +import org.elasticsearch.index.query.TermQueryBuilder;
31 import org.elasticsearch.search.SearchHit; 23 import org.elasticsearch.search.SearchHit;
32 import org.elasticsearch.search.SearchHits; 24 import org.elasticsearch.search.SearchHits;
33 import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; 25 import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
@@ -52,10 +44,30 @@ import org.springframework.context.ApplicationEventPublisher; @@ -52,10 +44,30 @@ import org.springframework.context.ApplicationEventPublisher;
52 import org.springframework.context.ApplicationEventPublisherAware; 44 import org.springframework.context.ApplicationEventPublisherAware;
53 import org.springframework.stereotype.Service; 45 import org.springframework.stereotype.Service;
54 46
55 -import java.io.UnsupportedEncodingException;  
56 -import java.net.URLDecoder;  
57 -import java.util.*;  
58 -import java.util.Map.Entry; 47 +import com.alibaba.fastjson.JSONArray;
  48 +import com.alibaba.fastjson.JSONObject;
  49 +import com.yoho.error.event.SearchEvent;
  50 +import com.yoho.search.base.utils.EventReportEnum;
  51 +import com.yoho.search.base.utils.ISearchConstants;
  52 +import com.yoho.search.core.es.agg.IAggregation;
  53 +import com.yoho.search.core.es.model.SearchParam;
  54 +import com.yoho.search.core.es.model.SearchResult;
  55 +import com.yoho.search.core.es.utils.IgnoreSomeException;
  56 +import com.yoho.search.service.aggregations.AggInterface;
  57 +import com.yoho.search.service.aggregations.impls.AggregationFactoryService;
  58 +import com.yoho.search.service.service.SearchCacheService;
  59 +import com.yoho.search.service.service.SearchCommonService;
  60 +import com.yoho.search.service.service.SearchServiceHelper;
  61 +import com.yoho.search.service.service.SearchSortSizeService;
  62 +import com.yoho.search.service.servicenew.IProductIndexService;
  63 +import com.yoho.search.service.servicenew.ISearchWithCacheService;
  64 +import com.yoho.search.service.servicenew.ISelectionsWithAdvanceService;
  65 +import com.yoho.search.service.servicenew.IShopsService;
  66 +import com.yoho.search.service.utils.HttpServletRequestUtils;
  67 +import com.yoho.search.service.utils.SearchApiResultUtils;
  68 +import com.yoho.search.service.utils.SearchRequestParams;
  69 +import com.yoho.search.service.vo.SearchApiResult;
  70 +import com.yoho.search.service.vo.SuggestApiResult;
59 71
60 @Service 72 @Service
61 public class SearchWithCacheServiceImpl implements ISearchWithCacheService, ApplicationEventPublisherAware { 73 public class SearchWithCacheServiceImpl implements ISearchWithCacheService, ApplicationEventPublisherAware {
@@ -447,11 +459,6 @@ public class SearchWithCacheServiceImpl implements ISearchWithCacheService, Appl @@ -447,11 +459,6 @@ public class SearchWithCacheServiceImpl implements ISearchWithCacheService, Appl
447 } 459 }
448 460
449 @Override 461 @Override
450 - public SearchApiResult sortSizes(SizeSortReqBO sizeSortReqBO) {  
451 - return searchSortSizeService.sortSizes(sizeSortReqBO);  
452 - }  
453 -  
454 - @Override  
455 public SearchApiResult groupBrands(Map<String, String> paramMap) { 462 public SearchApiResult groupBrands(Map<String, String> paramMap) {
456 try { 463 try {
457 logger.info("[func=groupBrands][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis()); 464 logger.info("[func=groupBrands][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());
1 package com.yoho.search.service.servicenew.impl; 1 package com.yoho.search.service.servicenew.impl;
2 2
3 -import com.alibaba.fastjson.JSONArray;  
4 -import com.alibaba.fastjson.JSONObject;  
5 -import com.yoho.error.event.SearchEvent;  
6 -import com.yoho.search.base.utils.EventReportEnum;  
7 -import com.yoho.search.base.utils.ISearchConstants;  
8 -import com.yoho.search.core.es.model.SearchParam;  
9 -import com.yoho.search.core.es.model.SearchResult;  
10 -import com.yoho.search.core.es.utils.IgnoreSomeException;  
11 -import com.yoho.search.core.es.utils.SearchParamUtils;  
12 -import com.yoho.search.service.aggregations.impls.AggregationFactoryService;  
13 -import com.yoho.search.service.cache.CacheEnum;  
14 -import com.yoho.search.service.cache.LocalCacheService;  
15 -import com.yoho.search.service.service.*;  
16 -import com.yoho.search.service.servicenew.IProductIndexService;  
17 -import com.yoho.search.service.servicenew.ISearchWithLocalCacheService;  
18 -import com.yoho.search.service.servicenew.ISelectionsWithAdvanceService;  
19 -import com.yoho.search.service.utils.*;  
20 -import com.yoho.search.service.vo.SearchApiResult; 3 +import java.util.ArrayList;
  4 +import java.util.Arrays;
  5 +import java.util.HashMap;
  6 +import java.util.HashSet;
  7 +import java.util.LinkedHashMap;
  8 +import java.util.List;
  9 +import java.util.Map;
  10 +import java.util.Set;
  11 +import java.util.concurrent.Callable;
  12 +
21 import org.apache.commons.lang.StringUtils; 13 import org.apache.commons.lang.StringUtils;
22 import org.elasticsearch.index.query.QueryBuilders; 14 import org.elasticsearch.index.query.QueryBuilders;
23 import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; 15 import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
@@ -26,7 +18,6 @@ import org.elasticsearch.search.aggregations.AggregationBuilders; @@ -26,7 +18,6 @@ import org.elasticsearch.search.aggregations.AggregationBuilders;
26 import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation; 18 import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
27 import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation.Bucket; 19 import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation.Bucket;
28 import org.elasticsearch.search.aggregations.bucket.terms.Terms; 20 import org.elasticsearch.search.aggregations.bucket.terms.Terms;
29 -import org.elasticsearch.search.builder.SearchSourceBuilder;  
30 import org.elasticsearch.search.sort.SortBuilder; 21 import org.elasticsearch.search.sort.SortBuilder;
31 import org.elasticsearch.search.sort.SortBuilders; 22 import org.elasticsearch.search.sort.SortBuilders;
32 import org.elasticsearch.search.sort.SortOrder; 23 import org.elasticsearch.search.sort.SortOrder;
@@ -37,552 +28,368 @@ import org.springframework.context.ApplicationEventPublisher; @@ -37,552 +28,368 @@ import org.springframework.context.ApplicationEventPublisher;
37 import org.springframework.context.ApplicationEventPublisherAware; 28 import org.springframework.context.ApplicationEventPublisherAware;
38 import org.springframework.stereotype.Service; 29 import org.springframework.stereotype.Service;
39 30
40 -import java.io.UnsupportedEncodingException;  
41 -import java.net.URLDecoder;  
42 -import java.util.*;  
43 -import java.util.concurrent.Callable; 31 +import com.alibaba.fastjson.JSONArray;
  32 +import com.alibaba.fastjson.JSONObject;
  33 +import com.yoho.error.event.SearchEvent;
  34 +import com.yoho.search.base.utils.EventReportEnum;
  35 +import com.yoho.search.base.utils.ISearchConstants;
  36 +import com.yoho.search.core.es.model.SearchParam;
  37 +import com.yoho.search.core.es.model.SearchResult;
  38 +import com.yoho.search.core.es.utils.IgnoreSomeException;
  39 +import com.yoho.search.service.aggregations.impls.AggregationFactoryService;
  40 +import com.yoho.search.service.cache.CacheEnum;
  41 +import com.yoho.search.service.cache.LocalCacheService;
  42 +import com.yoho.search.service.service.AggregationService;
  43 +import com.yoho.search.service.service.SearchCacheService;
  44 +import com.yoho.search.service.service.SearchCommonService;
  45 +import com.yoho.search.service.service.SearchKeyWordService;
  46 +import com.yoho.search.service.service.SearchServiceHelper;
  47 +import com.yoho.search.service.service.SearchSortSizeService;
  48 +import com.yoho.search.service.servicenew.IProductIndexService;
  49 +import com.yoho.search.service.servicenew.IProductListService;
  50 +import com.yoho.search.service.servicenew.ISearchWithLocalCacheService;
  51 +import com.yoho.search.service.servicenew.ISelectionsWithAdvanceService;
  52 +import com.yoho.search.service.utils.HttpServletRequestUtils;
  53 +import com.yoho.search.service.utils.LocalCacheKeyUtils;
  54 +import com.yoho.search.service.utils.SearchApiResultUtils;
  55 +import com.yoho.search.service.vo.SearchApiResult;
44 56
45 @Service 57 @Service
46 public class SearchWithLocalCacheServiceImpl implements ISearchWithLocalCacheService, ApplicationEventPublisherAware { 58 public class SearchWithLocalCacheServiceImpl implements ISearchWithLocalCacheService, ApplicationEventPublisherAware {
47 59
48 - private static final Logger logger = LoggerFactory.getLogger(SearchWithLocalCacheServiceImpl.class);  
49 -  
50 - private static Logger CACHE_MATCH_REQUEST = LoggerFactory.getLogger("CACHE_MATCH_REQUEST");  
51 -  
52 - @Autowired  
53 - private SearchServiceHelper searchServiceHelper;  
54 - @Autowired  
55 - private AggregationFactoryService aggregationFactoryService;  
56 - @Autowired  
57 - private AggregationService aggregationService;  
58 - @Autowired  
59 - private SearchCommonService searchCommonService;  
60 - @Autowired  
61 - private SearchAfterCacheService searchAfterCacheService;  
62 - @Autowired  
63 - private SearchSortSizeService searchSortSizeService;  
64 - @Autowired  
65 - private IProductIndexService productIndexService;  
66 - @Autowired  
67 - private LocalCacheService localCacheService;  
68 - @Autowired  
69 - private ISelectionsWithAdvanceService selectionsWithAdvanceService;  
70 - @Autowired  
71 - private SearchKeyWordService searchKeyWordService;  
72 - @Autowired  
73 - private SearchCacheService searchCacheService;  
74 -  
75 - private ApplicationEventPublisher publisher;  
76 -  
77 - @Override  
78 - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {  
79 - this.publisher = applicationEventPublisher;  
80 - }  
81 -  
82 - private void setHighlight(final Map<String, String> paramMap, SearchParam searchParam) {  
83 - if (StringUtils.isNotBlank(paramMap.get("highlight")) && "1".equals(paramMap.get("highlight")) && StringUtils.isNotBlank(paramMap.get("query"))) {  
84 - searchParam.setHighlight(true);  
85 - List<String> highlightFields = new ArrayList<String>();  
86 - highlightFields.add("productName.productName_ansj");  
87 - searchParam.setHighlightFields(highlightFields);  
88 - }  
89 - }  
90 -  
91 - /**  
92 - * 打印获取商品列表的ES语句  
93 - *  
94 - * @param paramMap  
95 - * @return  
96 - */  
97 - @Override  
98 - public SearchApiResult getESDsl(Map<String, String> paramMap) {  
99 - logger.info("[func=getESDsl][param={}]", paramMap);  
100 - try {  
101 - SearchParam searchParam = buildProductListSearchParam(paramMap);  
102 - SearchSourceBuilder searchSourceBuilder = SearchParamUtils.genSearchSourceBuilderFromSearchParam(searchParam);  
103 - SearchApiResult searchApiResult = new SearchApiResult();  
104 - searchApiResult.setData(searchSourceBuilder.toString());  
105 - logger.info("[func=getESDsl][dsl=\n{}]", searchApiResult.getData());  
106 - return searchApiResult;  
107 - } catch (Exception e) {  
108 - return SearchApiResultUtils.errorSearchApiResult("getESDsl", paramMap, e);  
109 - }  
110 - }  
111 -  
112 - private SearchParam buildProductListSearchParam(Map<String, String> paramMap) throws Exception {  
113 - // 1)验证查询条数  
114 - int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));  
115 - int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));  
116 - if (page < 1 || pageSize < 0) {  
117 - throw new IllegalArgumentException("分页参数不合法");  
118 - }  
119 - if (pageSize > 500) {  
120 - pageSize = 500;  
121 - }  
122 -  
123 - // 2)构建基本查询参数  
124 - paramMap.put("isProductList", "Y");//加个参数,表明是商品列表  
125 - SearchParam searchParam = new SearchParam();  
126 - searchParam.setQuery(searchServiceHelper.constructQueryBuilderForProductList(paramMap));  
127 - searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null));  
128 - setHighlight(paramMap, searchParam);  
129 - searchParam.setAggregationBuilders(null);  
130 - searchParam.setPage(page);  
131 - searchParam.setOffset((page - 1) * pageSize);  
132 - searchParam.setSize(pageSize);  
133 -  
134 - // 3)设置排序字段  
135 - // searchParam.setSortFields(searchServiceHelper.buildSort(paramMap));  
136 - searchParam.setSortBuilders(searchServiceHelper.buildSortList(paramMap));  
137 -  
138 - // 4)设置查询结果返回字段  
139 - if (StringUtils.isNotBlank(paramMap.get("resultFields"))) {  
140 - String resultFields = paramMap.get("resultFields");  
141 - searchParam.setResultFields(Arrays.asList(resultFields.split(",")));  
142 - }  
143 -  
144 - return searchParam;  
145 - }  
146 -  
147 - @Override  
148 - public SearchApiResult productList(Map<String, String> paramMap) {  
149 - try {  
150 - logger.info("[func=productList][param={}][begin={}]", paramMap, System.currentTimeMillis());  
151 -  
152 - //1)构造搜索参数  
153 - SearchParam searchParam = buildProductListSearchParam(paramMap);  
154 -  
155 - // 5)从缓存中获取数据  
156 - final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;  
157 - CacheEnum cacheEnum = CacheEnum.EHCACHE;  
158 - JSONObject cacheObject = searchCacheService.getJSONObjectFromCache(cacheEnum, indexName, searchParam);  
159 - if (cacheObject != null) {  
160 - CACHE_MATCH_REQUEST.info("match cache , url is :/productindex/productList.json?" + HttpServletRequestUtils.genParamString(paramMap));  
161 - return new SearchApiResult().setData(cacheObject);  
162 - }  
163 -  
164 - // 6)查询ES  
165 - SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);  
166 - if (searchResult == null) {  
167 - return new SearchApiResult().setCode(500).setMessage("execption");  
168 - }  
169 - // 7)记录关键字对应的查询结果  
170 - String queryWord = paramMap.get("query");  
171 - if (!StringUtils.isBlank(queryWord) && !searchServiceHelper.isQuerySkn(queryWord)) {  
172 - searchKeyWordService.recordKeyWordByResultCount(queryWord, searchResult.getTotal());  
173 - }  
174 - // 8)当返回结果为空时,先记录请求参数,然后修改operator为or并重新搜索,minimum修改为50%  
175 - if (StringUtils.isNotBlank(queryWord) && 0 == searchResult.getTotal()) {  
176 - searchKeyWordService.handleEmptyRecords(paramMap);  
177 - logger.info("search result is empty by operator of AND, will use operator of OR to reenforce search result");  
178 - searchParam.setQuery(searchServiceHelper.constructOrQueryBuilder(paramMap));  
179 - searchResult = searchCommonService.doSearch(indexName, searchParam);  
180 - }  
181 -  
182 - // 9)构造返回结果  
183 - JSONObject dataMap = new JSONObject();  
184 - dataMap.put("total", searchResult.getTotal());  
185 - dataMap.put("page", searchResult.getPage());  
186 - dataMap.put("page_size", searchParam.getSize());  
187 - dataMap.put("page_total", searchResult.getTotalPage());  
188 - dataMap.put("product_list", searchServiceHelper.getProductMapList(searchResult.getResultList()));  
189 -  
190 - // 10)将结果存进缓存  
191 - searchCacheService.addJSONObjectToCache(cacheEnum, indexName, searchParam, dataMap);  
192 - return new SearchApiResult().setData(dataMap);  
193 - } catch (Exception e) {  
194 - return SearchApiResultUtils.errorSearchApiResult("productList", paramMap, e);  
195 - }  
196 - }  
197 -  
198 - @Override  
199 - public SearchApiResult aggBrand(Map<String, String> paramMap) {  
200 - try {  
201 - logger.info("[func=aggBrand][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());  
202 - SearchParam searchParam = new SearchParam();  
203 - searchParam.setQuery(searchServiceHelper.constructQueryBuilder(paramMap));  
204 - searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null));  
205 - final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;  
206 -  
207 - // 1、从缓存中获取  
208 - SearchParam searchParamClone = searchParam.clone();  
209 - CacheEnum cacheEnum = CacheEnum.EHCACHE;  
210 - JSONArray cacheJSONArray = searchCacheService.getJSONArrayFromCache(cacheEnum, indexName, searchParamClone);  
211 - if (cacheJSONArray != null) {  
212 - CACHE_MATCH_REQUEST.info("match cache , url is :/productindex/aggBrand.json?" + HttpServletRequestUtils.genParamString(paramMap));  
213 - return new SearchApiResult().setData(cacheJSONArray);  
214 - }  
215 - // 2、从ES中获取  
216 - JSONObject jsonObject = aggregationService.getBrandAggregationResultWithOutCache(searchParam, paramMap, true);  
217 - if (jsonObject == null) {  
218 - return new SearchApiResult().setData(500).setMessage("exception");  
219 - }  
220 - // 3、生成结果并且加入缓存  
221 - JSONArray brandJSONArray = jsonObject.getJSONArray("brandAgg");  
222 - if (brandJSONArray != null) {  
223 - searchCacheService.addJSONArrayToCache(cacheEnum, indexName, searchParamClone, brandJSONArray);  
224 - }  
225 - return new SearchApiResult().setData(brandJSONArray);  
226 -  
227 - } catch (Exception e) {  
228 - return SearchApiResultUtils.errorSearchApiResult("aggBrand", paramMap, e);  
229 - }  
230 - }  
231 -  
232 - @Override  
233 - public SearchApiResult brands(Map<String, String> paramMap) {  
234 - try {  
235 - logger.info("[func=brands][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());  
236 - // 1、构造查询参数  
237 - SearchParam searchParam = new SearchParam();  
238 - searchParam.setQuery(searchServiceHelper.constructQueryBuilder(paramMap));  
239 - searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null));  
240 -  
241 - // 2、构造聚合参数  
242 - List<AbstractAggregationBuilder> list = new ArrayList<AbstractAggregationBuilder>();  
243 - list.add(AggregationBuilders.terms("brandAlifAgg").field("brandAlif").size(1000).order(Terms.Order.term(true))  
244 - .subAggregation(AggregationBuilders.terms("brandAgg").field("brandId").size(1000)));  
245 - searchParam.setAggregationBuilders(list);  
246 - searchParam.setSize(0);  
247 -  
248 - // 3、brand数据量比较大,走本地缓存  
249 - final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;  
250 - CacheEnum cacheEnum = CacheEnum.EHCACHE;  
251 - JSONObject cacheObject = searchCacheService.getJSONObjectFromCache(cacheEnum, indexName, searchParam);  
252 - if (cacheObject != null) {  
253 - CACHE_MATCH_REQUEST.info("match cache , url is :/brands.json?" + HttpServletRequestUtils.genParamString(paramMap));  
254 - return new SearchApiResult().setData(cacheObject);  
255 - }  
256 - // 4、查询ES  
257 - SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);  
258 - SearchApiResult searchApiResult = new SearchApiResult().setMessage("brand List.");  
259 - if (searchResult == null || searchResult.getAggMaps() == null) {  
260 - return searchApiResult.setCode(500);  
261 - }  
262 - Map<String, Aggregation> aggregationResult = searchResult.getAggMaps();  
263 - if (!aggregationResult.containsKey("brandAlifAgg")) {  
264 - return searchApiResult;  
265 - }  
266 - // 5、构造返回结果并加入缓存  
267 - JSONObject result = new JSONObject();  
268 - result.put("brands", makeBrandResponse(((MultiBucketsAggregation) aggregationResult.get("brandAlifAgg"))));  
269 - searchCacheService.addJSONObjectToCache(cacheEnum, indexName, searchParam, result);  
270 - return searchApiResult.setData(result);  
271 - } catch (Exception e) {  
272 - publisher.publishEvent(new SearchEvent(EventReportEnum.SEARCHCONTROLLER_BRANDS.getEventName(), EventReportEnum.SEARCHCONTROLLER_BRANDS.getFunctionName(),  
273 - EventReportEnum.SEARCHCONTROLLER_BRANDS.getMoudleName(), "exception", IgnoreSomeException.filterSomeException(e), null));  
274 - return SearchApiResultUtils.errorSearchApiResult("brands", paramMap, e);  
275 - }  
276 - }  
277 -  
278 - /**  
279 - * 制作品牌报文  
280 - */  
281 - private Map<String, JSONArray> makeBrandResponse(MultiBucketsAggregation aggregation) throws Exception {  
282 - // 1)获取每个brandAlif对应的brandIds  
283 - Map<String, List<String>> brandAlif2BrandIds = new LinkedHashMap<String, List<String>>();  
284 - for (Bucket brandAlifBucket : aggregation.getBuckets()) {  
285 - String brandAlif = brandAlifBucket.getKeyAsString();  
286 - List<String> brandIds = new ArrayList<String>();  
287 - MultiBucketsAggregation brandAggs = (MultiBucketsAggregation) brandAlifBucket.getAggregations().asMap().get("brandAgg");  
288 - for (Bucket brandIdBucket : brandAggs.getBuckets()) {  
289 - brandIds.addAll(Arrays.asList(brandIdBucket.getKeyAsString().split(",")));  
290 - }  
291 - brandAlif2BrandIds.put(brandAlif, brandIds);  
292 - }  
293 - // 2)获取所有的品牌id  
294 - Set<String> brandIdSet = new HashSet<String>();  
295 - for (Map.Entry<String, List<String>> entry : brandAlif2BrandIds.entrySet()) {  
296 - brandIdSet.addAll(entry.getValue());  
297 - }  
298 - // 3)获取所有的品牌数据  
299 - JSONArray jsonArray = searchCommonService.doMultiGet(ISearchConstants.INDEX_NAME_BRAND, brandIdSet, null);  
300 - Map<String, JSONObject> brandIdMap = new HashMap<String, JSONObject>();  
301 - for (int index = 0; index < jsonArray.size(); index++) {  
302 - JSONObject brandJSONObject = jsonArray.getJSONObject(index);  
303 - brandIdMap.put(brandJSONObject.getString("id"), brandJSONObject);  
304 - }  
305 - // 4)构造真正的数据  
306 - Map<String, JSONArray> result = new LinkedHashMap<String, JSONArray>();  
307 - for (Map.Entry<String, List<String>> entry : brandAlif2BrandIds.entrySet()) {  
308 - String brandAlif = entry.getKey();  
309 - JSONArray brands = new JSONArray();  
310 - for (String brandId : entry.getValue()) {  
311 - JSONObject brand = brandIdMap.get(brandId);  
312 - if (brand != null) {  
313 - brands.add(brand);  
314 - }  
315 - }  
316 - result.put(brandAlif, brands);  
317 - }  
318 - return result;  
319 - }  
320 -  
321 - @Override  
322 - public SearchApiResult brandList(Map<String, String> paramMap) {  
323 - try {  
324 - logger.info("[func=brandList][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());  
325 -  
326 - // 1)构建参数  
327 - SearchParam searchParam = new SearchParam();  
328 - searchParam.setSize(10000);  
329 - searchParam.setQuery(QueryBuilders.matchAllQuery());  
330 -  
331 - // 2、brand数据量比较大,走本地缓存。guavacache缓存中获取result,没有到es中获取  
332 - final String indexName = ISearchConstants.INDEX_NAME_BRAND;  
333 - CacheEnum cacheEnum = CacheEnum.EHCACHE;  
334 - JSONArray cacheJSONArray = searchCacheService.getJSONArrayFromCache(cacheEnum, indexName, searchParam);  
335 - if (cacheJSONArray != null) {  
336 - CACHE_MATCH_REQUEST.info("match cache , url is :/brand/list.json?" + HttpServletRequestUtils.genParamString(paramMap));  
337 - return new SearchApiResult().setData(cacheJSONArray);  
338 - }  
339 - SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_BRAND, searchParam);  
340 - if (searchResult == null || searchResult.getResultList().isEmpty()) {  
341 - return new SearchApiResult().setData(400).setMessage("empty result");  
342 - }  
343 - List<Map<String, Object>> result = searchResult.getResultList();  
344 - JSONArray jsonArray = new JSONArray();  
345 - for (Map<String, Object> map : result) {  
346 - Map<String, Object> dataMap = new HashMap<>();  
347 - dataMap.put("id", map.get("id"));  
348 - dataMap.put("brand_alif", map.get("brandAlif"));  
349 - dataMap.put("brand_name_en", map.get("brandNameEn"));  
350 - dataMap.put("brand_domain", map.get("brandDomain"));  
351 - dataMap.put("is_hot", map.get("isHot"));  
352 - dataMap.put("hot_keyword", map.get("hotKeyword"));  
353 - dataMap.put("brand_name_cn", map.get("brandNameCn"));  
354 - dataMap.put("brand_ico", map.get("brandIco"));  
355 - dataMap.put("brand_name", map.get("brandName"));  
356 - dataMap.put("brand_keyword", map.get("brandKeyword"));  
357 - jsonArray.add(dataMap);  
358 - }  
359 - searchCacheService.addJSONArrayToCache(cacheEnum, indexName, searchParam, jsonArray);  
360 - return new SearchApiResult().setMessage("brands info").setData(jsonArray);  
361 - } catch (Exception e) {  
362 - publisher.publishEvent(new SearchEvent(EventReportEnum.BRANDCONTROLLER_BRAND_LIST.getEventName(), EventReportEnum.BRANDCONTROLLER_BRAND_LIST.getFunctionName(),  
363 - EventReportEnum.BRANDCONTROLLER_BRAND_LIST.getMoudleName(), "exception", IgnoreSomeException.filterSomeException(e), null));  
364 - return SearchApiResultUtils.errorSearchApiResult("brandList", paramMap, e);  
365 - }  
366 - }  
367 -  
368 - @Override  
369 - public SearchApiResult sort_size_products(Map<String, String> paramMap) {  
370 - try {  
371 - logger.info("[func=sort_size_products][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());  
372 - // 1、先判断参数是否需要聚合【聚合不走storageSku索引】  
373 - JSONObject filter = new JSONObject();  
374 - if (paramMap.containsKey("needFilter") && "1".equals(paramMap.get("needFilter"))) {  
375 - // 1)获取不带全部品牌的聚合结果  
376 - paramMap.put("aggStorageSku", "aggStorageSku");  
377 - SearchApiResult filterResult = selectionsWithAdvanceService.getSelectionsWithAdvance(paramMap);  
378 - JSONObject filterJSONObject = this.getFilterResultFromJSONObject(filterResult);  
379 - if (filterJSONObject != null) {  
380 - filter = filterJSONObject;  
381 - }  
382 - // 2)获取品牌的聚合结果  
383 - SearchApiResult aggBrandResult = productIndexService.aggBrand(paramMap);  
384 - JSONArray aggBrand = this.getAggBrandResultFromJSONObject(aggBrandResult);  
385 - if (aggBrand != null && !aggBrand.isEmpty()) {  
386 - filter.put("brand", aggBrand);  
387 - }  
388 - }  
389 - // 2、从storageSku索引里根据参数获取skn[已使用本地缓存]  
390 - JSONObject productData = new JSONObject();  
391 - String[] productSkns = searchSortSizeService.getProductSknFromStorageSkuIndex(paramMap, 200);  
392 - if (productSkns == null || productSkns.length == 0) {  
393 - productData.put("total", 0);  
394 - productData.put("page_total", 0);  
395 - productData.put("page", 1);  
396 - productData.put("product_list", new JSONArray());  
397 - } else {  
398 - // 根据skn和其他参数查询结果[已使用本地缓存]  
399 - String productSknStr = StringSplitUtils.collectionToString(productSkns, ",");  
400 - paramMap.put(SearchRequestParams.PARAM_SYNC_SKN, productSknStr);  
401 - SearchApiResult searchApiResult = this.productList(paramMap);  
402 - productData = getProductResultFromJSONObject(searchApiResult);  
403 - }  
404 -  
405 - // 3、拼装真正的结果  
406 - JSONObject realData = new JSONObject();  
407 - if (filter != null && !filter.isEmpty()) {  
408 - realData.put("filter", filter);  
409 - }  
410 - if (productData != null) {  
411 - realData.putAll(productData);  
412 - }  
413 - return new SearchApiResult().setData(realData);  
414 - } catch (Exception e) {  
415 - return SearchApiResultUtils.errorSearchApiResult("sort_size_products", paramMap, e);  
416 - }  
417 - }  
418 -  
419 - private JSONObject getFilterResultFromJSONObject(SearchApiResult aggResult) {  
420 - try {  
421 - if (aggResult == null) {  
422 - return null;  
423 - }  
424 - JSONObject data = (JSONObject) aggResult.getData();  
425 - return data.getJSONObject("filter");  
426 - } catch (Exception e) {  
427 - logger.error(e.getMessage(), e);  
428 - return null;  
429 - }  
430 - }  
431 -  
432 - private JSONArray getAggBrandResultFromJSONObject(SearchApiResult aggBrandResult) {  
433 - try {  
434 - if (aggBrandResult == null) {  
435 - return null;  
436 - }  
437 - return (JSONArray) aggBrandResult.getData();  
438 - } catch (Exception e) {  
439 - logger.error(e.getMessage(), e);  
440 - return null;  
441 - }  
442 - }  
443 -  
444 - private JSONObject getProductResultFromJSONObject(SearchApiResult aggResult) {  
445 - try {  
446 - if (aggResult == null) {  
447 - return null;  
448 - }  
449 - return (JSONObject) aggResult.getData();  
450 - } catch (Exception e) {  
451 - logger.error(e.getMessage(), e);  
452 - return null;  
453 - }  
454 - }  
455 -  
456 - @Override  
457 - public SearchApiResult productPool(Map<String, String> paramMap) {  
458 - try {  
459 - long begin = System.currentTimeMillis();  
460 - logger.info("[func=searchProductPool][param={}][begin={}]", paramMap.toString(), begin);  
461 - // 1)如果poolId为空返回  
462 - if (StringUtils.isBlank(paramMap.get("filter_poolId"))) {  
463 - return new SearchApiResult().setCode(400).setMessage("filter_poolId参数为空");  
464 - }  
465 - // 2)如果有order参数就走老逻辑  
466 - if (StringUtils.isNotBlank(paramMap.get("order"))) {  
467 - return this.productList(paramMap);  
468 - }  
469 - // 3)检测分页参数  
470 - int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));  
471 - int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));  
472 - if (page < 1 || pageSize < 0) {  
473 - return new SearchApiResult().setCode(400).setMessage("分页参数错误");  
474 - }  
475 - if (pageSize > 500) {  
476 - pageSize = 500;  
477 - }  
478 - // 4)先进行商品池索引搜索,为空则直接返回  
479 - JSONObject productPoolResult = getProductPoolSknListOrderByDefault(paramMap, page, pageSize);  
480 - JSONArray productSknList = productPoolResult.getJSONArray("productSknList");  
481 - if (productPoolResult == null || productPoolResult.isEmpty() || productSknList == null || productSknList.isEmpty()) {  
482 - Map<String, Object> dataMap = new HashMap<String, Object>();  
483 - dataMap.put("total", 0);  
484 - dataMap.put("page", page);  
485 - dataMap.put("page_total", 0);  
486 - dataMap.put("product_list", new JSONArray());  
487 - return new SearchApiResult().setData(dataMap);  
488 - }  
489 -  
490 - // 5)构造参数  
491 - SearchParam searchParam = new SearchParam();  
492 - searchParam.setPage(1);// 这里直接用1就行,不然会有BUG  
493 - searchParam.setOffset(0);  
494 - searchParam.setSize(productSknList.size());  
495 - searchParam.setQuery(searchServiceHelper.constructQueryBuilderWithPoolId(paramMap, productSknList));  
496 - searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null));  
497 -  
498 - // 6)进行检索,使用本地缓存  
499 - final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;  
500 - String localCacheKey = LocalCacheKeyUtils.guavaCacheKey(indexName, searchParam);  
501 - List<Map<String, Object>> productList = localCacheService.getOrAddToLocalCache(localCacheKey, new Callable<List<Map<String, Object>>>() {  
502 - @Override  
503 - public List<Map<String, Object>> call() throws Exception {  
504 - SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);  
505 - // 将searchResult转化为map返回--需要把aggregation转化为需要的结构  
506 - if (searchResult == null) {  
507 - return new ArrayList<Map<String, Object>>();  
508 - }  
509 - return searchServiceHelper.getProductMapList(searchResult.getResultList());  
510 - }  
511 - });  
512 - SearchApiResult searchApiResult = new SearchApiResult();  
513 - JSONObject data = new JSONObject();  
514 - data.put("total", productPoolResult.getLong("total"));  
515 - data.put("page", productPoolResult.getIntValue("page"));  
516 - data.put("page_total", productPoolResult.getLong("page_total"));  
517 - data.put("product_list", productList);  
518 - return searchApiResult.setData(data);  
519 - } catch (Exception e) {  
520 - return SearchApiResultUtils.errorSearchApiResult("productPool", paramMap, e);  
521 - }  
522 - }  
523 -  
524 -  
525 - /**  
526 - * 搜索商品池  
527 - *  
528 - * @param paramMap  
529 - * @return  
530 - * @throws Exception  
531 - */  
532 - private JSONObject getProductPoolSknListOrderByDefault(Map<String, String> paramMap, int page, int pageSize) {  
533 - try {  
534 - // 检测分页参数  
535 - // 解析参数转化为检索条件--SearchParam  
536 - SearchParam searchParam = new SearchParam();  
537 - // 设置查询条数  
538 - searchParam.setPage(page);  
539 - searchParam.setOffset((page - 1) * pageSize);  
540 - searchParam.setSize(pageSize);  
541 - // 构建filter  
542 - searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null));  
543 -  
544 - // 设置排序字段  
545 - // LinkedHashMap<String, String> sortFields = new  
546 - // LinkedHashMap<String, String>();  
547 - // sortFields.put("id", "asc");  
548 - // searchParam.setSortFields(sortFields);  
549 - List<SortBuilder> sortBuilders = new ArrayList<SortBuilder>();  
550 - sortBuilders.add(SortBuilders.fieldSort("id").order(SortOrder.ASC));  
551 - searchParam.setSortBuilders(sortBuilders);  
552 -  
553 - // 对productpool索引检索  
554 - final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_POOL;  
555 - String localCacheKey = LocalCacheKeyUtils.guavaCacheKey(indexName, searchParam);  
556 - JSONObject result = localCacheService.getOrAddToLocalCache(localCacheKey, new Callable<JSONObject>() {  
557 - @Override  
558 - public JSONObject call() throws Exception {  
559 - SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);  
560 - // 将searchResult转化为map返回--需要把aggregation转化为需要的结构  
561 - if (searchResult == null) {  
562 - return new JSONObject();  
563 - }  
564 - JSONObject result = new JSONObject();  
565 - List<Integer> productSknList = new ArrayList<>();  
566 - for (Map<String, Object> map : searchResult.getResultList()) {  
567 - Object productSkn = map.get("productSkn");  
568 - if (productSkn != null) {  
569 - productSknList.add(Integer.valueOf(productSkn.toString()));  
570 - }  
571 - }  
572 - result.put("total", searchResult.getTotal());  
573 - result.put("page", searchResult.getPage());  
574 - result.put("page_total", searchResult.getTotalPage());  
575 - result.put("productSknList", productSknList);  
576 - return result;  
577 - }  
578 - });  
579 - return result;  
580 - } catch (Exception e) {  
581 - logger.error(e.getMessage(), e);  
582 - return new JSONObject();  
583 - }  
584 - }  
585 -  
586 - 60 + private static final Logger logger = LoggerFactory.getLogger(SearchWithLocalCacheServiceImpl.class);
  61 +
  62 + private static Logger CACHE_MATCH_REQUEST = LoggerFactory.getLogger("CACHE_MATCH_REQUEST");
  63 +
  64 + @Autowired
  65 + private SearchServiceHelper searchServiceHelper;
  66 + @Autowired
  67 + private AggregationFactoryService aggregationFactoryService;
  68 + @Autowired
  69 + private AggregationService aggregationService;
  70 + @Autowired
  71 + private SearchCommonService searchCommonService;
  72 + @Autowired
  73 + private SearchAfterCacheService searchAfterCacheService;
  74 + @Autowired
  75 + private SearchSortSizeService searchSortSizeService;
  76 + @Autowired
  77 + private IProductIndexService productIndexService;
  78 + @Autowired
  79 + private LocalCacheService localCacheService;
  80 + @Autowired
  81 + private ISelectionsWithAdvanceService selectionsWithAdvanceService;
  82 + @Autowired
  83 + private SearchKeyWordService searchKeyWordService;
  84 + @Autowired
  85 + private SearchCacheService searchCacheService;
  86 + @Autowired
  87 + private IProductListService productListService;
  88 +
  89 + private ApplicationEventPublisher publisher;
  90 +
  91 + @Override
  92 + public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
  93 + this.publisher = applicationEventPublisher;
  94 + }
  95 +
  96 + @Override
  97 + public SearchApiResult aggBrand(Map<String, String> paramMap) {
  98 + try {
  99 + logger.info("[func=aggBrand][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());
  100 + SearchParam searchParam = new SearchParam();
  101 + searchParam.setQuery(searchServiceHelper.constructQueryBuilder(paramMap));
  102 + searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null));
  103 + final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
  104 +
  105 + // 1、从缓存中获取
  106 + SearchParam searchParamClone = searchParam.clone();
  107 + CacheEnum cacheEnum = CacheEnum.EHCACHE;
  108 + JSONArray cacheJSONArray = searchCacheService.getJSONArrayFromCache(cacheEnum, indexName, searchParamClone);
  109 + if (cacheJSONArray != null) {
  110 + CACHE_MATCH_REQUEST.info("match cache , url is :/productindex/aggBrand.json?" + HttpServletRequestUtils.genParamString(paramMap));
  111 + return new SearchApiResult().setData(cacheJSONArray);
  112 + }
  113 + // 2、从ES中获取
  114 + JSONObject jsonObject = aggregationService.getBrandAggregationResultWithOutCache(searchParam, paramMap, true);
  115 + if (jsonObject == null) {
  116 + return new SearchApiResult().setData(500).setMessage("exception");
  117 + }
  118 + // 3、生成结果并且加入缓存
  119 + JSONArray brandJSONArray = jsonObject.getJSONArray("brandAgg");
  120 + if (brandJSONArray != null) {
  121 + searchCacheService.addJSONArrayToCache(cacheEnum, indexName, searchParamClone, brandJSONArray);
  122 + }
  123 + return new SearchApiResult().setData(brandJSONArray);
  124 +
  125 + } catch (Exception e) {
  126 + return SearchApiResultUtils.errorSearchApiResult("aggBrand", paramMap, e);
  127 + }
  128 + }
  129 +
  130 + @Override
  131 + public SearchApiResult brands(Map<String, String> paramMap) {
  132 + try {
  133 + logger.info("[func=brands][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());
  134 + // 1、构造查询参数
  135 + SearchParam searchParam = new SearchParam();
  136 + searchParam.setQuery(searchServiceHelper.constructQueryBuilder(paramMap));
  137 + searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null));
  138 +
  139 + // 2、构造聚合参数
  140 + List<AbstractAggregationBuilder> list = new ArrayList<AbstractAggregationBuilder>();
  141 + list.add(AggregationBuilders.terms("brandAlifAgg").field("brandAlif").size(1000).order(Terms.Order.term(true))
  142 + .subAggregation(AggregationBuilders.terms("brandAgg").field("brandId").size(1000)));
  143 + searchParam.setAggregationBuilders(list);
  144 + searchParam.setSize(0);
  145 +
  146 + // 3、brand数据量比较大,走本地缓存
  147 + final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
  148 + CacheEnum cacheEnum = CacheEnum.EHCACHE;
  149 + JSONObject cacheObject = searchCacheService.getJSONObjectFromCache(cacheEnum, indexName, searchParam);
  150 + if (cacheObject != null) {
  151 + CACHE_MATCH_REQUEST.info("match cache , url is :/brands.json?" + HttpServletRequestUtils.genParamString(paramMap));
  152 + return new SearchApiResult().setData(cacheObject);
  153 + }
  154 + // 4、查询ES
  155 + SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
  156 + SearchApiResult searchApiResult = new SearchApiResult().setMessage("brand List.");
  157 + if (searchResult == null || searchResult.getAggMaps() == null) {
  158 + return searchApiResult.setCode(500);
  159 + }
  160 + Map<String, Aggregation> aggregationResult = searchResult.getAggMaps();
  161 + if (!aggregationResult.containsKey("brandAlifAgg")) {
  162 + return searchApiResult;
  163 + }
  164 + // 5、构造返回结果并加入缓存
  165 + JSONObject result = new JSONObject();
  166 + result.put("brands", makeBrandResponse(((MultiBucketsAggregation) aggregationResult.get("brandAlifAgg"))));
  167 + searchCacheService.addJSONObjectToCache(cacheEnum, indexName, searchParam, result);
  168 + return searchApiResult.setData(result);
  169 + } catch (Exception e) {
  170 + publisher.publishEvent(new SearchEvent(EventReportEnum.SEARCHCONTROLLER_BRANDS.getEventName(), EventReportEnum.SEARCHCONTROLLER_BRANDS.getFunctionName(),
  171 + EventReportEnum.SEARCHCONTROLLER_BRANDS.getMoudleName(), "exception", IgnoreSomeException.filterSomeException(e), null));
  172 + return SearchApiResultUtils.errorSearchApiResult("brands", paramMap, e);
  173 + }
  174 + }
  175 +
  176 + /**
  177 + * 制作品牌报文
  178 + */
  179 + private Map<String, JSONArray> makeBrandResponse(MultiBucketsAggregation aggregation) throws Exception {
  180 + // 1)获取每个brandAlif对应的brandIds
  181 + Map<String, List<String>> brandAlif2BrandIds = new LinkedHashMap<String, List<String>>();
  182 + for (Bucket brandAlifBucket : aggregation.getBuckets()) {
  183 + String brandAlif = brandAlifBucket.getKeyAsString();
  184 + List<String> brandIds = new ArrayList<String>();
  185 + MultiBucketsAggregation brandAggs = (MultiBucketsAggregation) brandAlifBucket.getAggregations().asMap().get("brandAgg");
  186 + for (Bucket brandIdBucket : brandAggs.getBuckets()) {
  187 + brandIds.addAll(Arrays.asList(brandIdBucket.getKeyAsString().split(",")));
  188 + }
  189 + brandAlif2BrandIds.put(brandAlif, brandIds);
  190 + }
  191 + // 2)获取所有的品牌id
  192 + Set<String> brandIdSet = new HashSet<String>();
  193 + for (Map.Entry<String, List<String>> entry : brandAlif2BrandIds.entrySet()) {
  194 + brandIdSet.addAll(entry.getValue());
  195 + }
  196 + // 3)获取所有的品牌数据
  197 + JSONArray jsonArray = searchCommonService.doMultiGet(ISearchConstants.INDEX_NAME_BRAND, brandIdSet, null);
  198 + Map<String, JSONObject> brandIdMap = new HashMap<String, JSONObject>();
  199 + for (int index = 0; index < jsonArray.size(); index++) {
  200 + JSONObject brandJSONObject = jsonArray.getJSONObject(index);
  201 + brandIdMap.put(brandJSONObject.getString("id"), brandJSONObject);
  202 + }
  203 + // 4)构造真正的数据
  204 + Map<String, JSONArray> result = new LinkedHashMap<String, JSONArray>();
  205 + for (Map.Entry<String, List<String>> entry : brandAlif2BrandIds.entrySet()) {
  206 + String brandAlif = entry.getKey();
  207 + JSONArray brands = new JSONArray();
  208 + for (String brandId : entry.getValue()) {
  209 + JSONObject brand = brandIdMap.get(brandId);
  210 + if (brand != null) {
  211 + brands.add(brand);
  212 + }
  213 + }
  214 + result.put(brandAlif, brands);
  215 + }
  216 + return result;
  217 + }
  218 +
  219 + @Override
  220 + public SearchApiResult brandList(Map<String, String> paramMap) {
  221 + try {
  222 + logger.info("[func=brandList][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());
  223 +
  224 + // 1)构建参数
  225 + SearchParam searchParam = new SearchParam();
  226 + searchParam.setSize(10000);
  227 + searchParam.setQuery(QueryBuilders.matchAllQuery());
  228 +
  229 + // 2、brand数据量比较大,走本地缓存。guavacache缓存中获取result,没有到es中获取
  230 + final String indexName = ISearchConstants.INDEX_NAME_BRAND;
  231 + CacheEnum cacheEnum = CacheEnum.EHCACHE;
  232 + JSONArray cacheJSONArray = searchCacheService.getJSONArrayFromCache(cacheEnum, indexName, searchParam);
  233 + if (cacheJSONArray != null) {
  234 + CACHE_MATCH_REQUEST.info("match cache , url is :/brand/list.json?" + HttpServletRequestUtils.genParamString(paramMap));
  235 + return new SearchApiResult().setData(cacheJSONArray);
  236 + }
  237 + SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_BRAND, searchParam);
  238 + if (searchResult == null || searchResult.getResultList().isEmpty()) {
  239 + return new SearchApiResult().setData(400).setMessage("empty result");
  240 + }
  241 + List<Map<String, Object>> result = searchResult.getResultList();
  242 + JSONArray jsonArray = new JSONArray();
  243 + for (Map<String, Object> map : result) {
  244 + Map<String, Object> dataMap = new HashMap<>();
  245 + dataMap.put("id", map.get("id"));
  246 + dataMap.put("brand_alif", map.get("brandAlif"));
  247 + dataMap.put("brand_name_en", map.get("brandNameEn"));
  248 + dataMap.put("brand_domain", map.get("brandDomain"));
  249 + dataMap.put("is_hot", map.get("isHot"));
  250 + dataMap.put("hot_keyword", map.get("hotKeyword"));
  251 + dataMap.put("brand_name_cn", map.get("brandNameCn"));
  252 + dataMap.put("brand_ico", map.get("brandIco"));
  253 + dataMap.put("brand_name", map.get("brandName"));
  254 + dataMap.put("brand_keyword", map.get("brandKeyword"));
  255 + jsonArray.add(dataMap);
  256 + }
  257 + searchCacheService.addJSONArrayToCache(cacheEnum, indexName, searchParam, jsonArray);
  258 + return new SearchApiResult().setMessage("brands info").setData(jsonArray);
  259 + } catch (Exception e) {
  260 + publisher.publishEvent(new SearchEvent(EventReportEnum.BRANDCONTROLLER_BRAND_LIST.getEventName(), EventReportEnum.BRANDCONTROLLER_BRAND_LIST.getFunctionName(),
  261 + EventReportEnum.BRANDCONTROLLER_BRAND_LIST.getMoudleName(), "exception", IgnoreSomeException.filterSomeException(e), null));
  262 + return SearchApiResultUtils.errorSearchApiResult("brandList", paramMap, e);
  263 + }
  264 + }
  265 +
  266 + @Override
  267 + public SearchApiResult productPool(Map<String, String> paramMap) {
  268 + try {
  269 + long begin = System.currentTimeMillis();
  270 + logger.info("[func=searchProductPool][param={}][begin={}]", paramMap.toString(), begin);
  271 + // 1)如果poolId为空返回
  272 + if (StringUtils.isBlank(paramMap.get("filter_poolId"))) {
  273 + return new SearchApiResult().setCode(400).setMessage("filter_poolId参数为空");
  274 + }
  275 + // 2)如果有order参数就走老逻辑
  276 + if (StringUtils.isNotBlank(paramMap.get("order"))) {
  277 + return productListService.productList(paramMap);
  278 + }
  279 + // 3)检测分页参数
  280 + int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
  281 + int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
  282 + if (page < 1 || pageSize < 0) {
  283 + return new SearchApiResult().setCode(400).setMessage("分页参数错误");
  284 + }
  285 + if (pageSize > 500) {
  286 + pageSize = 500;
  287 + }
  288 + // 4)先进行商品池索引搜索,为空则直接返回
  289 + JSONObject productPoolResult = getProductPoolSknListOrderByDefault(paramMap, page, pageSize);
  290 + JSONArray productSknList = productPoolResult.getJSONArray("productSknList");
  291 + if (productPoolResult == null || productPoolResult.isEmpty() || productSknList == null || productSknList.isEmpty()) {
  292 + Map<String, Object> dataMap = new HashMap<String, Object>();
  293 + dataMap.put("total", 0);
  294 + dataMap.put("page", page);
  295 + dataMap.put("page_total", 0);
  296 + dataMap.put("product_list", new JSONArray());
  297 + return new SearchApiResult().setData(dataMap);
  298 + }
  299 +
  300 + // 5)构造参数
  301 + SearchParam searchParam = new SearchParam();
  302 + searchParam.setPage(1);// 这里直接用1就行,不然会有BUG
  303 + searchParam.setOffset(0);
  304 + searchParam.setSize(productSknList.size());
  305 + searchParam.setQuery(searchServiceHelper.constructQueryBuilderWithPoolId(paramMap, productSknList));
  306 + searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null));
  307 +
  308 + // 6)进行检索,使用本地缓存
  309 + final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
  310 + String localCacheKey = LocalCacheKeyUtils.guavaCacheKey(indexName, searchParam);
  311 + List<Map<String, Object>> productList = localCacheService.getOrAddToLocalCache(localCacheKey, new Callable<List<Map<String, Object>>>() {
  312 + @Override
  313 + public List<Map<String, Object>> call() throws Exception {
  314 + SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
  315 + // 将searchResult转化为map返回--需要把aggregation转化为需要的结构
  316 + if (searchResult == null) {
  317 + return new ArrayList<Map<String, Object>>();
  318 + }
  319 + return searchServiceHelper.getProductMapList(searchResult.getResultList());
  320 + }
  321 + });
  322 + SearchApiResult searchApiResult = new SearchApiResult();
  323 + JSONObject data = new JSONObject();
  324 + data.put("total", productPoolResult.getLong("total"));
  325 + data.put("page", productPoolResult.getIntValue("page"));
  326 + data.put("page_total", productPoolResult.getLong("page_total"));
  327 + data.put("product_list", productList);
  328 + return searchApiResult.setData(data);
  329 + } catch (Exception e) {
  330 + return SearchApiResultUtils.errorSearchApiResult("productPool", paramMap, e);
  331 + }
  332 + }
  333 +
  334 + /**
  335 + * 搜索商品池
  336 + *
  337 + * @param paramMap
  338 + * @return
  339 + * @throws Exception
  340 + */
  341 + private JSONObject getProductPoolSknListOrderByDefault(Map<String, String> paramMap, int page, int pageSize) {
  342 + try {
  343 + // 检测分页参数
  344 + // 解析参数转化为检索条件--SearchParam
  345 + SearchParam searchParam = new SearchParam();
  346 + // 设置查询条数
  347 + searchParam.setPage(page);
  348 + searchParam.setOffset((page - 1) * pageSize);
  349 + searchParam.setSize(pageSize);
  350 + // 构建filter
  351 + searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null));
  352 +
  353 + // 设置排序字段
  354 + // LinkedHashMap<String, String> sortFields = new
  355 + // LinkedHashMap<String, String>();
  356 + // sortFields.put("id", "asc");
  357 + // searchParam.setSortFields(sortFields);
  358 + List<SortBuilder> sortBuilders = new ArrayList<SortBuilder>();
  359 + sortBuilders.add(SortBuilders.fieldSort("id").order(SortOrder.ASC));
  360 + searchParam.setSortBuilders(sortBuilders);
  361 +
  362 + // 对productpool索引检索
  363 + final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_POOL;
  364 + String localCacheKey = LocalCacheKeyUtils.guavaCacheKey(indexName, searchParam);
  365 + JSONObject result = localCacheService.getOrAddToLocalCache(localCacheKey, new Callable<JSONObject>() {
  366 + @Override
  367 + public JSONObject call() throws Exception {
  368 + SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
  369 + // 将searchResult转化为map返回--需要把aggregation转化为需要的结构
  370 + if (searchResult == null) {
  371 + return new JSONObject();
  372 + }
  373 + JSONObject result = new JSONObject();
  374 + List<Integer> productSknList = new ArrayList<>();
  375 + for (Map<String, Object> map : searchResult.getResultList()) {
  376 + Object productSkn = map.get("productSkn");
  377 + if (productSkn != null) {
  378 + productSknList.add(Integer.valueOf(productSkn.toString()));
  379 + }
  380 + }
  381 + result.put("total", searchResult.getTotal());
  382 + result.put("page", searchResult.getPage());
  383 + result.put("page_total", searchResult.getTotalPage());
  384 + result.put("productSknList", productSknList);
  385 + return result;
  386 + }
  387 + });
  388 + return result;
  389 + } catch (Exception e) {
  390 + logger.error(e.getMessage(), e);
  391 + return new JSONObject();
  392 + }
  393 + }
587 394
588 } 395 }