Merge branch 'zf_agg' into gray
Showing
13 changed files
with
307 additions
and
94 deletions
@@ -3,6 +3,7 @@ package com.yoho.search.service.aggregations.impls; | @@ -3,6 +3,7 @@ package com.yoho.search.service.aggregations.impls; | ||
3 | import com.yoho.search.core.es.agg.IAggregation; | 3 | import com.yoho.search.core.es.agg.IAggregation; |
4 | import com.yoho.search.service.aggregations.AggInterface; | 4 | import com.yoho.search.service.aggregations.AggInterface; |
5 | import com.yoho.search.service.service.SearchCommonService; | 5 | import com.yoho.search.service.service.SearchCommonService; |
6 | +import com.yoho.search.service.servicenew.IShopsService; | ||
6 | import com.yoho.search.service.servicenew.impl.SearchAfterCacheService; | 7 | import com.yoho.search.service.servicenew.impl.SearchAfterCacheService; |
7 | import org.springframework.beans.factory.annotation.Autowired; | 8 | import org.springframework.beans.factory.annotation.Autowired; |
8 | import org.springframework.stereotype.Service; | 9 | import org.springframework.stereotype.Service; |
@@ -17,6 +18,9 @@ public class AggregationFactoryService { | @@ -17,6 +18,9 @@ public class AggregationFactoryService { | ||
17 | @Autowired | 18 | @Autowired |
18 | private SearchAfterCacheService searchAfterCacheService; | 19 | private SearchAfterCacheService searchAfterCacheService; |
19 | 20 | ||
21 | + @Autowired | ||
22 | + private IShopsService shopsService; | ||
23 | + | ||
20 | public IAggregation getSubAggregationByType(int type, Map<String, String> paramMap) { | 24 | public IAggregation getSubAggregationByType(int type, Map<String, String> paramMap) { |
21 | IAggregation iAggregation = null; | 25 | IAggregation iAggregation = null; |
22 | switch (type) { | 26 | switch (type) { |
@@ -127,4 +131,11 @@ public class AggregationFactoryService { | @@ -127,4 +131,11 @@ public class AggregationFactoryService { | ||
127 | return new SortGroupAggregation(paramMap); | 131 | return new SortGroupAggregation(paramMap); |
128 | } | 132 | } |
129 | 133 | ||
134 | + public IAggregation getKeywordAggregation(int aggCount) { | ||
135 | + return new KeywordAggregation(aggCount); | ||
136 | + } | ||
137 | + | ||
138 | + public IAggregation getShopAggregation(int aggCount) { | ||
139 | + return new ShopAggregation(shopsService, aggCount); | ||
140 | + } | ||
130 | } | 141 | } |
1 | +package com.yoho.search.service.aggregations.impls; | ||
2 | + | ||
3 | +import org.apache.commons.collections.CollectionUtils; | ||
4 | +import org.elasticsearch.search.aggregations.Aggregation; | ||
5 | + | ||
6 | +import java.util.Arrays; | ||
7 | +import java.util.List; | ||
8 | +import java.util.Map; | ||
9 | + | ||
10 | +public class KeywordAggregation extends AbstractSingleFieldAggregation { | ||
11 | + | ||
12 | + private static final List<String> IGNORE_KEYWORDS = Arrays.asList("正常", "无", "中", "中国"); | ||
13 | + | ||
14 | + public KeywordAggregation(int count) { | ||
15 | + super(count); | ||
16 | + } | ||
17 | + | ||
18 | + @Override | ||
19 | + public String aggName() { | ||
20 | + return "keywordAgg"; | ||
21 | + } | ||
22 | + | ||
23 | + @Override | ||
24 | + protected String getField() { | ||
25 | + return "productAttrField"; | ||
26 | + } | ||
27 | + | ||
28 | + @Override | ||
29 | + public Object getAggregationResponseMap(Map<String, Aggregation> aggMaps) { | ||
30 | + List<String> valueList = (List<String>)super.getAggregationResponseMap(aggMaps); | ||
31 | + if(CollectionUtils.isNotEmpty(valueList)){ | ||
32 | + valueList.removeAll(IGNORE_KEYWORDS); | ||
33 | + } | ||
34 | + | ||
35 | + return valueList; | ||
36 | + } | ||
37 | +} |
1 | +package com.yoho.search.service.aggregations.impls; | ||
2 | + | ||
3 | +import com.alibaba.fastjson.JSONObject; | ||
4 | +import com.yoho.search.service.servicenew.IShopsService; | ||
5 | +import com.yoho.search.service.utils.SearchRequestParams; | ||
6 | +import com.yoho.search.service.vo.SearchApiResult; | ||
7 | +import org.apache.commons.collections.CollectionUtils; | ||
8 | +import org.elasticsearch.search.aggregations.Aggregation; | ||
9 | + | ||
10 | +import java.util.ArrayList; | ||
11 | +import java.util.HashMap; | ||
12 | +import java.util.List; | ||
13 | +import java.util.Map; | ||
14 | +import java.util.stream.Collectors; | ||
15 | + | ||
16 | +public class ShopAggregation extends AbstractSingleFieldAggregation { | ||
17 | + | ||
18 | + private IShopsService shopsService; | ||
19 | + | ||
20 | + public ShopAggregation(IShopsService shopsService, int count) { | ||
21 | + super(count); | ||
22 | + this.shopsService = shopsService; | ||
23 | + } | ||
24 | + | ||
25 | + @Override | ||
26 | + public String aggName() { | ||
27 | + return "shopAgg"; | ||
28 | + } | ||
29 | + | ||
30 | + @Override | ||
31 | + protected String getField() { | ||
32 | + return "shopId"; | ||
33 | + } | ||
34 | + | ||
35 | + @Override | ||
36 | + public Object getAggregationResponseMap(Map<String, Aggregation> aggMaps) { | ||
37 | + List<String> shopIdList = (List<String>) super.getAggregationResponseMap(aggMaps); | ||
38 | + if (CollectionUtils.isNotEmpty(shopIdList)) { | ||
39 | + shopIdList = shopIdList.stream().map(Integer::valueOf).filter(shopId -> shopId != null && shopId.intValue() > 0).map(String::valueOf).collect(Collectors.toList()); | ||
40 | + } | ||
41 | + | ||
42 | + if (CollectionUtils.isEmpty(shopIdList)) { | ||
43 | + return new ArrayList<>(); | ||
44 | + } | ||
45 | + | ||
46 | + // 调用Shops索引查询确保shopId有效 | ||
47 | + Map<String, String> shopsParam = new HashMap<>(); | ||
48 | + shopsParam.put(SearchRequestParams.PARAM_SEARCH_SHOP, shopIdList.stream().collect(Collectors.joining(","))); | ||
49 | + shopsParam.put(SearchRequestParams.SHOPS_PARAM_STATUS, "1"); | ||
50 | + SearchApiResult searchApiResult = shopsService.getShopsInfo(shopsParam); | ||
51 | + if (searchApiResult == null || searchApiResult.getData() == null || searchApiResult.getCode() != 200) { | ||
52 | + return new ArrayList<>(); | ||
53 | + } | ||
54 | + | ||
55 | + JSONObject jsonObject = (JSONObject) searchApiResult.getData(); | ||
56 | + Map<String, Map<String, Object>> shopsInfo = (Map<String, Map<String, Object>>) jsonObject.get("shopInfo"); | ||
57 | + return shopsInfo == null || shopsInfo.isEmpty() ? new ArrayList<>() : shopsInfo.values().stream().collect(Collectors.toList()); | ||
58 | + } | ||
59 | +} |
@@ -175,4 +175,32 @@ public class ProductIndexController implements ApplicationEventPublisherAware { | @@ -175,4 +175,32 @@ public class ProductIndexController implements ApplicationEventPublisherAware { | ||
175 | Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request); | 175 | Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request); |
176 | return productIndexService.aggSpecialoffer(paramMap); | 176 | return productIndexService.aggSpecialoffer(paramMap); |
177 | } | 177 | } |
178 | + | ||
179 | + /** | ||
180 | + * 从商品列表聚合关键词,随机返回关键词 | ||
181 | + * | ||
182 | + * @param request | ||
183 | + * @return | ||
184 | + */ | ||
185 | + @DownGradeAble(key = "recommendKeyword") | ||
186 | + @RequestMapping(method = RequestMethod.GET, value = "/recommendKeyword") | ||
187 | + @ResponseBody | ||
188 | + public SearchApiResult recommendKeyword(HttpServletRequest request) { | ||
189 | + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request); | ||
190 | + return productIndexService.aggKeywords(paramMap); | ||
191 | + } | ||
192 | + | ||
193 | + /** | ||
194 | + * 聚合关键词 | ||
195 | + * | ||
196 | + * @param request | ||
197 | + * @return | ||
198 | + */ | ||
199 | + @DownGradeAble(key = "recommendShop") | ||
200 | + @RequestMapping(method = RequestMethod.GET, value = "/recommendShop") | ||
201 | + @ResponseBody | ||
202 | + public SearchApiResult recommendShop(HttpServletRequest request) { | ||
203 | + Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request); | ||
204 | + return productIndexService.aggShops(paramMap); | ||
205 | + } | ||
178 | } | 206 | } |
@@ -40,22 +40,21 @@ public class ToolsController { | @@ -40,22 +40,21 @@ public class ToolsController { | ||
40 | /** | 40 | /** |
41 | * 获取热搜词结果 | 41 | * 获取热搜词结果 |
42 | * | 42 | * |
43 | - * @param request | ||
44 | * @return | 43 | * @return |
45 | */ | 44 | */ |
46 | @RequestMapping(method = RequestMethod.GET, value = "/hotSearchWords") | 45 | @RequestMapping(method = RequestMethod.GET, value = "/hotSearchWords") |
47 | @ResponseBody | 46 | @ResponseBody |
48 | public SearchApiResult hotSearchWords(@RequestParam(defaultValue = "1000") int limit, | 47 | public SearchApiResult hotSearchWords(@RequestParam(defaultValue = "1000") int limit, |
49 | @RequestParam(defaultValue = "false") boolean onlyShowKeyWord, | 48 | @RequestParam(defaultValue = "false") boolean onlyShowKeyWord, |
50 | - @RequestParam(defaultValue = "true") boolean returnTodayRecords) { | 49 | + @RequestParam(defaultValue = "") String dateStr) { |
51 | SearchApiResult searchApiResult = new SearchApiResult(); | 50 | SearchApiResult searchApiResult = new SearchApiResult(); |
52 | - Map<String, Object> results = searchKeyWordService.getHotkeyWords(limit, onlyShowKeyWord ? false : returnTodayRecords); | 51 | + Map<String, Object> results = searchKeyWordService.getHotkeyWords(limit, dateStr); |
53 | if (!onlyShowKeyWord) { | 52 | if (!onlyShowKeyWord) { |
54 | return searchApiResult.setData(results); | 53 | return searchApiResult.setData(results); |
55 | } | 54 | } |
56 | 55 | ||
57 | List<String> keywords = new ArrayList<>(); | 56 | List<String> keywords = new ArrayList<>(); |
58 | - for (KeyWordWithCount keyWordWithCount : (List<KeyWordWithCount>) results.get("-1")) { | 57 | + for (KeyWordWithCount keyWordWithCount : (List<KeyWordWithCount>) results.get("keywords")) { |
59 | keywords.add(keyWordWithCount.getKeyWord()); | 58 | keywords.add(keyWordWithCount.getKeyWord()); |
60 | } | 59 | } |
61 | return searchApiResult.setData(keywords); | 60 | return searchApiResult.setData(keywords); |
@@ -70,15 +69,15 @@ public class ToolsController { | @@ -70,15 +69,15 @@ public class ToolsController { | ||
70 | @ResponseBody | 69 | @ResponseBody |
71 | public SearchApiResult emptyResultKeywords(@RequestParam(defaultValue = "1000") int limit, | 70 | public SearchApiResult emptyResultKeywords(@RequestParam(defaultValue = "1000") int limit, |
72 | @RequestParam(defaultValue = "false") boolean onlyShowKeyWord, | 71 | @RequestParam(defaultValue = "false") boolean onlyShowKeyWord, |
73 | - @RequestParam(defaultValue = "true") boolean returnTodayRecords) { | 72 | + @RequestParam(defaultValue = "") String dateStr) { |
74 | SearchApiResult searchApiResult = new SearchApiResult(); | 73 | SearchApiResult searchApiResult = new SearchApiResult(); |
75 | - Map<String, Object> results = searchKeyWordService.getEmptyKeyWords(limit, onlyShowKeyWord ? false : returnTodayRecords); | 74 | + Map<String, Object> results = searchKeyWordService.getEmptyKeyWords(limit, dateStr); |
76 | if (!onlyShowKeyWord) { | 75 | if (!onlyShowKeyWord) { |
77 | return searchApiResult.setData(results); | 76 | return searchApiResult.setData(results); |
78 | } | 77 | } |
79 | 78 | ||
80 | List<String> keywords = new ArrayList<>(); | 79 | List<String> keywords = new ArrayList<>(); |
81 | - for (KeyWordWithCount keyWordWithCount : (List<KeyWordWithCount>) results.get("-1")) { | 80 | + for (KeyWordWithCount keyWordWithCount : (List<KeyWordWithCount>) results.get("keywords")) { |
82 | keywords.add(keyWordWithCount.getKeyWord()); | 81 | keywords.add(keyWordWithCount.getKeyWord()); |
83 | } | 82 | } |
84 | return searchApiResult.setData(keywords); | 83 | return searchApiResult.setData(keywords); |
@@ -87,22 +86,44 @@ public class ToolsController { | @@ -87,22 +86,44 @@ public class ToolsController { | ||
87 | /** | 86 | /** |
88 | * 获取一页搜索词 | 87 | * 获取一页搜索词 |
89 | * | 88 | * |
90 | - * @param request | ||
91 | * @return | 89 | * @return |
92 | */ | 90 | */ |
93 | @RequestMapping(method = RequestMethod.GET, value = "/lessKeyWords") | 91 | @RequestMapping(method = RequestMethod.GET, value = "/lessKeyWords") |
94 | @ResponseBody | 92 | @ResponseBody |
95 | public SearchApiResult lessKeyWords(@RequestParam(defaultValue = "1000") int limit, | 93 | public SearchApiResult lessKeyWords(@RequestParam(defaultValue = "1000") int limit, |
96 | @RequestParam(defaultValue = "false") boolean onlyShowKeyWord, | 94 | @RequestParam(defaultValue = "false") boolean onlyShowKeyWord, |
97 | - @RequestParam(defaultValue = "true") boolean returnTodayRecords) { | 95 | + @RequestParam(defaultValue = "") String dateStr) { |
98 | SearchApiResult searchApiResult = new SearchApiResult(); | 96 | SearchApiResult searchApiResult = new SearchApiResult(); |
99 | - Map<String, Object> results = searchKeyWordService.getLessKeyWords(limit, onlyShowKeyWord ? false : returnTodayRecords); | 97 | + Map<String, Object> results = searchKeyWordService.getLessKeyWords(limit, dateStr); |
100 | if (!onlyShowKeyWord) { | 98 | if (!onlyShowKeyWord) { |
101 | return searchApiResult.setData(results); | 99 | return searchApiResult.setData(results); |
102 | } | 100 | } |
103 | 101 | ||
104 | List<String> keywords = new ArrayList<>(); | 102 | List<String> keywords = new ArrayList<>(); |
105 | - for (KeyWordWithCount keyWordWithCount : (List<KeyWordWithCount>) results.get("-1")) { | 103 | + for (KeyWordWithCount keyWordWithCount : (List<KeyWordWithCount>) results.get("keywords")) { |
104 | + keywords.add(keyWordWithCount.getKeyWord()); | ||
105 | + } | ||
106 | + return searchApiResult.setData(keywords); | ||
107 | + } | ||
108 | + | ||
109 | + /** | ||
110 | + * 获取需要推荐的关键词 | ||
111 | + * | ||
112 | + * @return | ||
113 | + */ | ||
114 | + @RequestMapping(method = RequestMethod.GET, value = "/recomKeyWords") | ||
115 | + @ResponseBody | ||
116 | + public SearchApiResult recomKeyWords(@RequestParam(defaultValue = "1000") int limit, | ||
117 | + @RequestParam(defaultValue = "false") boolean onlyShowKeyWord, | ||
118 | + @RequestParam(defaultValue = "") String dateStr) { | ||
119 | + SearchApiResult searchApiResult = new SearchApiResult(); | ||
120 | + Map<String, Object> results = searchKeyWordService.getNeedRecomKeyWords(limit, dateStr); | ||
121 | + if (!onlyShowKeyWord) { | ||
122 | + return searchApiResult.setData(results); | ||
123 | + } | ||
124 | + | ||
125 | + List<String> keywords = new ArrayList<>(); | ||
126 | + for (KeyWordWithCount keyWordWithCount : (List<KeyWordWithCount>) results.get("keywords")) { | ||
106 | keywords.add(keyWordWithCount.getKeyWord()); | 127 | keywords.add(keyWordWithCount.getKeyWord()); |
107 | } | 128 | } |
108 | return searchApiResult.setData(keywords); | 129 | return searchApiResult.setData(keywords); |
@@ -124,7 +145,6 @@ public class ToolsController { | @@ -124,7 +145,6 @@ public class ToolsController { | ||
124 | /** | 145 | /** |
125 | * 获取分词结果 | 146 | * 获取分词结果 |
126 | * | 147 | * |
127 | - * @param request | ||
128 | * @return | 148 | * @return |
129 | */ | 149 | */ |
130 | @RequestMapping(method = RequestMethod.GET, value = "/analyzeTokens") | 150 | @RequestMapping(method = RequestMethod.GET, value = "/analyzeTokens") |
@@ -138,7 +158,6 @@ public class ToolsController { | @@ -138,7 +158,6 @@ public class ToolsController { | ||
138 | /** | 158 | /** |
139 | * 清除本地缓存 | 159 | * 清除本地缓存 |
140 | * | 160 | * |
141 | - * @param request 请求 | ||
142 | * @return | 161 | * @return |
143 | */ | 162 | */ |
144 | @RequestMapping(method = RequestMethod.GET, value = "/clearLocalCache") | 163 | @RequestMapping(method = RequestMethod.GET, value = "/clearLocalCache") |
1 | package com.yoho.search.service.service; | 1 | package com.yoho.search.service.service; |
2 | 2 | ||
3 | -import java.util.ArrayList; | ||
4 | -import java.util.Arrays; | ||
5 | -import java.util.List; | ||
6 | -import java.util.Map; | ||
7 | - | 3 | +import com.alibaba.fastjson.JSONObject; |
4 | +import com.yoho.error.event.SearchEvent; | ||
5 | +import com.yoho.search.base.utils.EventReportEnum; | ||
6 | +import com.yoho.search.base.utils.ISearchConstants; | ||
7 | +import com.yoho.search.core.es.agg.IAggregation; | ||
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.service.aggregations.impls.AggregationFactoryService; | ||
12 | +import com.yoho.search.service.service.helper.SearchServiceHelper; | ||
13 | +import com.yoho.search.service.utils.SearchRequestParams; | ||
8 | import org.apache.commons.lang.StringUtils; | 14 | import org.apache.commons.lang.StringUtils; |
9 | import org.elasticsearch.index.query.BoolQueryBuilder; | 15 | import org.elasticsearch.index.query.BoolQueryBuilder; |
10 | import org.elasticsearch.index.query.QueryBuilder; | 16 | import org.elasticsearch.index.query.QueryBuilder; |
@@ -17,17 +23,10 @@ import org.springframework.context.ApplicationEventPublisher; | @@ -17,17 +23,10 @@ import org.springframework.context.ApplicationEventPublisher; | ||
17 | import org.springframework.context.ApplicationEventPublisherAware; | 23 | import org.springframework.context.ApplicationEventPublisherAware; |
18 | import org.springframework.stereotype.Service; | 24 | import org.springframework.stereotype.Service; |
19 | 25 | ||
20 | -import com.alibaba.fastjson.JSONObject; | ||
21 | -import com.yoho.error.event.SearchEvent; | ||
22 | -import com.yoho.search.base.utils.EventReportEnum; | ||
23 | -import com.yoho.search.base.utils.ISearchConstants; | ||
24 | -import com.yoho.search.core.es.agg.IAggregation; | ||
25 | -import com.yoho.search.core.es.model.SearchParam; | ||
26 | -import com.yoho.search.core.es.model.SearchResult; | ||
27 | -import com.yoho.search.core.es.utils.IgnoreSomeException; | ||
28 | -import com.yoho.search.service.aggregations.impls.AggregationFactoryService; | ||
29 | -import com.yoho.search.service.service.helper.SearchServiceHelper; | ||
30 | -import com.yoho.search.service.utils.SearchRequestParams; | 26 | +import java.util.ArrayList; |
27 | +import java.util.Arrays; | ||
28 | +import java.util.List; | ||
29 | +import java.util.Map; | ||
31 | 30 | ||
32 | @Service | 31 | @Service |
33 | public class AggregationService implements ApplicationEventPublisherAware { | 32 | public class AggregationService implements ApplicationEventPublisherAware { |
@@ -324,4 +323,29 @@ public class AggregationService implements ApplicationEventPublisherAware { | @@ -324,4 +323,29 @@ public class AggregationService implements ApplicationEventPublisherAware { | ||
324 | return this.getAggNameAndResponse(isSecialofferAggregation, searchParam, paramMap, filterParamName); | 323 | return this.getAggNameAndResponse(isSecialofferAggregation, searchParam, paramMap, filterParamName); |
325 | } | 324 | } |
326 | 325 | ||
326 | + /** | ||
327 | + * 获取商品关键词的聚合,来源与风格、款式和属性。 | ||
328 | + * | ||
329 | + * @param searchParam | ||
330 | + * @param paramMap | ||
331 | + * @return | ||
332 | + * @throws Exception | ||
333 | + */ | ||
334 | + public JSONObject getKeywordAggregationResult(SearchParam searchParam, Map<String, String> paramMap, int aggCount) throws Exception { | ||
335 | + IAggregation keywordAggregation = aggregationFactoryService.getKeywordAggregation(aggCount); | ||
336 | + return this.getAggNameAndResponse(keywordAggregation, searchParam, paramMap, null); | ||
337 | + } | ||
338 | + | ||
339 | + /** | ||
340 | + * 获取商品关键词的聚合,来源与风格、款式和属性。 | ||
341 | + * | ||
342 | + * @param searchParam | ||
343 | + * @param paramMap | ||
344 | + * @return | ||
345 | + * @throws Exception | ||
346 | + */ | ||
347 | + public JSONObject getShopAggregationResult(SearchParam searchParam, Map<String, String> paramMap, int aggCount) throws Exception { | ||
348 | + IAggregation keywordAggregation = aggregationFactoryService.getShopAggregation(aggCount); | ||
349 | + return this.getAggNameAndResponse(keywordAggregation, searchParam, paramMap, null); | ||
350 | + } | ||
327 | } | 351 | } |
@@ -22,7 +22,6 @@ import org.springframework.stereotype.Service; | @@ -22,7 +22,6 @@ import org.springframework.stereotype.Service; | ||
22 | import org.springframework.util.Assert; | 22 | import org.springframework.util.Assert; |
23 | 23 | ||
24 | import javax.annotation.Resource; | 24 | import javax.annotation.Resource; |
25 | -import java.text.SimpleDateFormat; | ||
26 | import java.util.*; | 25 | import java.util.*; |
27 | import java.util.concurrent.ExecutionException; | 26 | import java.util.concurrent.ExecutionException; |
28 | import java.util.concurrent.ExecutorService; | 27 | import java.util.concurrent.ExecutorService; |
@@ -40,8 +39,6 @@ public class SearchKeyWordService { | @@ -40,8 +39,6 @@ public class SearchKeyWordService { | ||
40 | 39 | ||
41 | private static final Logger logger = LoggerFactory.getLogger(SearchKeyWordService.class); | 40 | private static final Logger logger = LoggerFactory.getLogger(SearchKeyWordService.class); |
42 | 41 | ||
43 | - private static final Logger EMPTY_RESULT = LoggerFactory.getLogger("EMPTY_RESULT"); | ||
44 | - | ||
45 | @Resource(name = "yhNoSyncZSetOperations") | 42 | @Resource(name = "yhNoSyncZSetOperations") |
46 | private YHZSetOperations<String, String> yhNoSyncZSetOperations; | 43 | private YHZSetOperations<String, String> yhNoSyncZSetOperations; |
47 | 44 | ||
@@ -118,10 +115,6 @@ public class SearchKeyWordService { | @@ -118,10 +115,6 @@ public class SearchKeyWordService { | ||
118 | } | 115 | } |
119 | } | 116 | } |
120 | 117 | ||
121 | - public void recordSuggestTip(String queryWord) { | ||
122 | - recordKeyWord(RedisKeys.YOHO_SEARCH_KEYWORDS_TIPS, queryWord); | ||
123 | - } | ||
124 | - | ||
125 | // 异步的做法是防止redis报错影响搜索主流程 | 118 | // 异步的做法是防止redis报错影响搜索主流程 |
126 | private void recordKeyWord(String redisKeyTemplate, String queryWord) { | 119 | private void recordKeyWord(String redisKeyTemplate, String queryWord) { |
127 | service.submit(new Runnable() { | 120 | service.submit(new Runnable() { |
@@ -183,79 +176,61 @@ public class SearchKeyWordService { | @@ -183,79 +176,61 @@ public class SearchKeyWordService { | ||
183 | } | 176 | } |
184 | } | 177 | } |
185 | 178 | ||
186 | - public Double getKeywordCount(String redisKeyTemplate, String queryWord){ | 179 | + public void recordSuggestRecom(String queryWord) { |
180 | + recordKeyWord(RedisKeys.YOHO_SEARCH_KEYWORDS_TIPS, queryWord); | ||
181 | + } | ||
182 | + | ||
183 | + public Double getKeywordCount(String redisKeyTemplate, String queryWord) { | ||
187 | try { | 184 | try { |
188 | return yhNoSyncZSetOperations.score(RedisKeys.getRedisKey4Yesterday(redisKeyTemplate), queryWord); | 185 | return yhNoSyncZSetOperations.score(RedisKeys.getRedisKey4Yesterday(redisKeyTemplate), queryWord); |
189 | - }catch (Exception e){ | 186 | + } catch (Exception e) { |
190 | return null; | 187 | return null; |
191 | } | 188 | } |
192 | } | 189 | } |
193 | 190 | ||
194 | // 获取【热搜】toplist | 191 | // 获取【热搜】toplist |
195 | - public Map<String, Object> getHotkeyWords(int limit, boolean isReturnTodayRecords) { | ||
196 | - return this.getListByScoreDesc(RedisKeys.YOHO_SEARCH_KEYWORDS_HOT, limit, isReturnTodayRecords); | 192 | + public Map<String, Object> getHotkeyWords(int limit, String dateStr) { |
193 | + return this.getListByScoreDesc(RedisKeys.YOHO_SEARCH_KEYWORDS_HOT, limit, dateStr); | ||
197 | } | 194 | } |
198 | 195 | ||
199 | // 获取空结果的toplist | 196 | // 获取空结果的toplist |
200 | - public Map<String, Object> getEmptyKeyWords(int limit, boolean isReturnTodayRecords) { | ||
201 | - return this.getListByScoreDesc(RedisKeys.YOHO_SEARCH_KEYWORDS_EMPTY, limit, isReturnTodayRecords); | 197 | + public Map<String, Object> getEmptyKeyWords(int limit, String dateStr) { |
198 | + return this.getListByScoreDesc(RedisKeys.YOHO_SEARCH_KEYWORDS_EMPTY, limit, dateStr); | ||
202 | } | 199 | } |
203 | 200 | ||
204 | // 获取只有一页结果的toplist | 201 | // 获取只有一页结果的toplist |
205 | - public Map<String, Object> getLessKeyWords(int limit, boolean isReturnTodayRecords) { | ||
206 | - return this.getListByScoreDesc(RedisKeys.YOHO_SEARCH_KEYWORDS_LESS, limit, isReturnTodayRecords); | 202 | + public Map<String, Object> getLessKeyWords(int limit, String dateStr) { |
203 | + return this.getListByScoreDesc(RedisKeys.YOHO_SEARCH_KEYWORDS_LESS, limit, dateStr); | ||
204 | + } | ||
205 | + | ||
206 | + // 获取需要搜索推荐的关键词 | ||
207 | + public Map<String, Object> getNeedRecomKeyWords(int limit, String dateStr) { | ||
208 | + return this.getListByScoreDesc(RedisKeys.YOHO_SEARCH_KEYWORDS_TIPS, limit, dateStr); | ||
207 | } | 209 | } |
208 | 210 | ||
209 | - private Map<String, Object> getListByScoreDesc(String redisKeyTemplate, int limit, boolean isReturnTodayRecords) { | 211 | + private Map<String, Object> getListByScoreDesc(String redisKeyTemplate, int limit, String dateStr) { |
210 | Map<String, Object> resultMap = new HashMap<>(3); | 212 | Map<String, Object> resultMap = new HashMap<>(3); |
211 | - resultMap.put("dateForRedisKey", dateForRedisKey); | ||
212 | - if (this.dateForRedisKey == null) { | ||
213 | - return resultMap; | 213 | + |
214 | + String date = dateStr; | ||
215 | + if (StringUtils.isEmpty(date)) { | ||
216 | + date = this.dateForRedisKey; | ||
217 | + } | ||
218 | + if (StringUtils.isEmpty(date)) { | ||
219 | + date = DateUtil.DateToString(new Date(), DateStyle.YYYYMMDD); | ||
214 | } | 220 | } |
215 | 221 | ||
216 | - String redisKey = RedisKeys.getRedisKey4Yesterday(redisKeyTemplate); | 222 | + String redisKey = String.format(redisKeyTemplate, date); |
217 | Set<ZSetOperations.TypedTuple<String>> redisResults = yhNoSyncZSetOperations.reverseRangeWithScores(redisKey, 0, limit); | 223 | Set<ZSetOperations.TypedTuple<String>> redisResults = yhNoSyncZSetOperations.reverseRangeWithScores(redisKey, 0, limit); |
218 | List<KeyWordWithCount> results = new ArrayList<KeyWordWithCount>(); | 224 | List<KeyWordWithCount> results = new ArrayList<KeyWordWithCount>(); |
219 | for (TypedTuple<String> typedTuple : redisResults) { | 225 | for (TypedTuple<String> typedTuple : redisResults) { |
220 | results.add(new KeyWordWithCount(typedTuple.getValue(), (int) typedTuple.getScore().doubleValue())); | 226 | results.add(new KeyWordWithCount(typedTuple.getValue(), (int) typedTuple.getScore().doubleValue())); |
221 | } | 227 | } |
222 | 228 | ||
223 | - if (isReturnTodayRecords) { | ||
224 | - // 也返回今天的数据 | ||
225 | - String redisKey4Today = RedisKeys.getRedisKey4Today(redisKeyTemplate); | ||
226 | - Set<ZSetOperations.TypedTuple<String>> redisResults4Today = yhNoSyncZSetOperations.reverseRangeWithScores(redisKey4Today, 0, limit); | ||
227 | - List<KeyWordWithCount> results4Today = new ArrayList<KeyWordWithCount>(); | ||
228 | - for (TypedTuple<String> typedTuple : redisResults4Today) { | ||
229 | - results4Today.add(new KeyWordWithCount(typedTuple.getValue(), (int) typedTuple.getScore().doubleValue())); | ||
230 | - } | ||
231 | - | ||
232 | - resultMap.put("0", results4Today); | ||
233 | - } | ||
234 | - | ||
235 | resultMap.put("redisKey", redisKey); | 229 | resultMap.put("redisKey", redisKey); |
236 | - resultMap.put("-1", results); | 230 | + resultMap.put("keywords", results); |
237 | return resultMap; | 231 | return resultMap; |
238 | } | 232 | } |
239 | 233 | ||
240 | - public void handleEmptyRecords(Map<String, String> paramMap) { | ||
241 | - StringBuilder paramStringBuilder = new StringBuilder(); | ||
242 | - for (Map.Entry<String, String> entry : paramMap.entrySet()) { | ||
243 | - paramStringBuilder.append("&").append(entry.getKey()).append("=").append(entry.getValue()); | ||
244 | - } | ||
245 | - String paramString = paramStringBuilder.toString().replaceFirst("&", ""); | ||
246 | - EMPTY_RESULT.info("empty records for search.json: time[{}], param [{}]", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()), paramString); | ||
247 | - | ||
248 | - // 商品池或品类列表 为空,则告警 | ||
249 | - if (paramMap.get("filter_poolId") != null) {// || | ||
250 | - // paramMap.get("msort")!=null | ||
251 | - // || | ||
252 | - // paramMap.get("misort")!=null | ||
253 | - // || | ||
254 | - // paramMap.get("sort")!=null | ||
255 | - // /TODO | ||
256 | - } | ||
257 | - } | ||
258 | - | ||
259 | public String deleteRedisKey(String redisKey) { | 234 | public String deleteRedisKey(String redisKey) { |
260 | if (yhNoSyncRedisTemplate.hasKey(redisKey)) { | 235 | if (yhNoSyncRedisTemplate.hasKey(redisKey)) { |
261 | yhNoSyncRedisTemplate.delete(redisKey); | 236 | yhNoSyncRedisTemplate.delete(redisKey); |
1 | package com.yoho.search.service.servicenew; | 1 | package com.yoho.search.service.servicenew; |
2 | 2 | ||
3 | -import java.util.Map; | ||
4 | - | ||
5 | import com.yoho.search.service.vo.SearchApiResult; | 3 | import com.yoho.search.service.vo.SearchApiResult; |
6 | 4 | ||
5 | +import java.util.Map; | ||
6 | + | ||
7 | public interface IProductIndexService { | 7 | public interface IProductIndexService { |
8 | 8 | ||
9 | /** | 9 | /** |
@@ -83,4 +83,13 @@ public interface IProductIndexService { | @@ -83,4 +83,13 @@ public interface IProductIndexService { | ||
83 | * @return | 83 | * @return |
84 | */ | 84 | */ |
85 | public SearchApiResult aggSpecialoffer(Map<String, String> paramMap); | 85 | public SearchApiResult aggSpecialoffer(Map<String, String> paramMap); |
86 | + | ||
87 | + /** | ||
88 | + * 商品关键词的聚合,来源与风格、款式和属性。 | ||
89 | + * @param paramMap | ||
90 | + * @return | ||
91 | + */ | ||
92 | + SearchApiResult aggKeywords(Map<String, String> paramMap); | ||
93 | + | ||
94 | + SearchApiResult aggShops(Map<String, String> paramMap); | ||
86 | } | 95 | } |
@@ -29,4 +29,6 @@ public interface IShopsService { | @@ -29,4 +29,6 @@ public interface IShopsService { | ||
29 | * @return | 29 | * @return |
30 | */ | 30 | */ |
31 | public SearchApiResult searchShopsNew(Map<String, String> paramMap); | 31 | public SearchApiResult searchShopsNew(Map<String, String> paramMap); |
32 | + | ||
33 | + SearchApiResult getShopsInfo(Map<String, String> paramMap); | ||
32 | } | 34 | } |
1 | package com.yoho.search.service.servicenew.impl; | 1 | package com.yoho.search.service.servicenew.impl; |
2 | 2 | ||
3 | -import java.util.ArrayList; | ||
4 | -import java.util.List; | ||
5 | -import java.util.Map; | ||
6 | - | 3 | +import com.alibaba.fastjson.JSONObject; |
4 | +import com.yoho.error.event.SearchEvent; | ||
5 | +import com.yoho.search.base.utils.CollectionUtils; | ||
7 | import com.yoho.search.base.utils.EventReportEnum; | 6 | import com.yoho.search.base.utils.EventReportEnum; |
8 | import com.yoho.search.base.utils.JsonUtil; | 7 | import com.yoho.search.base.utils.JsonUtil; |
8 | +import com.yoho.search.core.es.model.SearchParam; | ||
9 | +import com.yoho.search.core.es.utils.IgnoreSomeException; | ||
9 | import com.yoho.search.service.service.AggregationService; | 10 | import com.yoho.search.service.service.AggregationService; |
10 | import com.yoho.search.service.service.SearchCommonService; | 11 | import com.yoho.search.service.service.SearchCommonService; |
11 | import com.yoho.search.service.service.helper.SearchServiceHelper; | 12 | import com.yoho.search.service.service.helper.SearchServiceHelper; |
12 | import com.yoho.search.service.servicenew.IProductIndexService; | 13 | import com.yoho.search.service.servicenew.IProductIndexService; |
13 | -import com.yoho.search.core.es.utils.IgnoreSomeException; | ||
14 | import com.yoho.search.service.vo.SearchApiResult; | 14 | import com.yoho.search.service.vo.SearchApiResult; |
15 | - | ||
16 | import org.apache.commons.lang.StringUtils; | 15 | import org.apache.commons.lang.StringUtils; |
17 | import org.slf4j.Logger; | 16 | import org.slf4j.Logger; |
18 | import org.slf4j.LoggerFactory; | 17 | import org.slf4j.LoggerFactory; |
@@ -21,9 +20,11 @@ import org.springframework.context.ApplicationEventPublisher; | @@ -21,9 +20,11 @@ import org.springframework.context.ApplicationEventPublisher; | ||
21 | import org.springframework.context.ApplicationEventPublisherAware; | 20 | import org.springframework.context.ApplicationEventPublisherAware; |
22 | import org.springframework.stereotype.Service; | 21 | import org.springframework.stereotype.Service; |
23 | 22 | ||
24 | -import com.alibaba.fastjson.JSONObject; | ||
25 | -import com.yoho.error.event.SearchEvent; | ||
26 | -import com.yoho.search.core.es.model.SearchParam; | 23 | +import java.util.ArrayList; |
24 | +import java.util.List; | ||
25 | +import java.util.Map; | ||
26 | +import java.util.Random; | ||
27 | +import java.util.stream.Collectors; | ||
27 | 28 | ||
28 | @Service | 29 | @Service |
29 | public class ProductIndexServiceImpl implements IProductIndexService,ApplicationEventPublisherAware { | 30 | public class ProductIndexServiceImpl implements IProductIndexService,ApplicationEventPublisherAware { |
@@ -245,4 +246,45 @@ public class ProductIndexServiceImpl implements IProductIndexService,Application | @@ -245,4 +246,45 @@ public class ProductIndexServiceImpl implements IProductIndexService,Application | ||
245 | } | 246 | } |
246 | }); | 247 | }); |
247 | } | 248 | } |
249 | + | ||
250 | + @Override | ||
251 | + public SearchApiResult aggKeywords(Map<String, String> paramMap) { | ||
252 | + final int randomKeywordCount = StringUtils.isBlank(paramMap.get("keyword_count")) ? 8 : Integer.parseInt(paramMap.get("keyword_count")); | ||
253 | + return this.getSearchApiResult("aggKeywords", paramMap, new Searcher() { | ||
254 | + @Override | ||
255 | + public Object getResult() throws Exception { | ||
256 | + SearchParam searchParam = getSearchParamFromMap(paramMap); | ||
257 | + JSONObject jsonObject = aggregationService.getKeywordAggregationResult(searchParam, paramMap, 50); | ||
258 | + List<String> keywordList = (List<String>) jsonObject.get("keywordAgg"); | ||
259 | + return getRandomKeywords(keywordList, randomKeywordCount); | ||
260 | + } | ||
261 | + }); | ||
262 | + } | ||
263 | + | ||
264 | + private List<String> getRandomKeywords(List<String> keywordList, int randomKeywordCount) { | ||
265 | + if (keywordList == null || keywordList.size() <= randomKeywordCount) { | ||
266 | + return keywordList; | ||
267 | + } | ||
268 | + | ||
269 | + return new Random().ints(0, keywordList.size()) | ||
270 | + .distinct() | ||
271 | + .limit(randomKeywordCount) | ||
272 | + .mapToObj(index -> keywordList.get(index)) | ||
273 | + .collect(Collectors.toList()); | ||
274 | + } | ||
275 | + | ||
276 | + @Override | ||
277 | + public SearchApiResult aggShops(Map<String, String> paramMap) { | ||
278 | + final int page = StringUtils.isBlank(paramMap.get("shop_page")) ? 1 : Integer.parseInt(paramMap.get("shop_page")); | ||
279 | + final int count = StringUtils.isBlank(paramMap.get("shop_count")) ? 1 : Integer.parseInt(paramMap.get("shop_count")); | ||
280 | + return this.getSearchApiResult("aggShops", paramMap, new Searcher() { | ||
281 | + @Override | ||
282 | + public Object getResult() throws Exception { | ||
283 | + SearchParam searchParam = getSearchParamFromMap(paramMap); | ||
284 | + JSONObject jsonObject = aggregationService.getShopAggregationResult(searchParam, paramMap, 30); | ||
285 | + List<Map<String, Object>> shopList = (List<Map<String, Object>>) jsonObject.get("shopAgg"); | ||
286 | + return CollectionUtils.memoryPaging(shopList, page, count); | ||
287 | + } | ||
288 | + }); | ||
289 | + } | ||
248 | } | 290 | } |
@@ -145,6 +145,8 @@ public class SearchRecommendServiceImpl implements ISearchRecommendService { | @@ -145,6 +145,8 @@ public class SearchRecommendServiceImpl implements ISearchRecommendService { | ||
145 | } catch (Exception e) { | 145 | } catch (Exception e) { |
146 | logger.error("[func=recommend][queryWord=" + queryWord + "]", e); | 146 | logger.error("[func=recommend][queryWord=" + queryWord + "]", e); |
147 | return defaultSuggestRecommendation(); | 147 | return defaultSuggestRecommendation(); |
148 | + } finally { | ||
149 | + searchKeyWordService.recordSuggestRecom(queryWord); | ||
148 | } | 150 | } |
149 | } | 151 | } |
150 | 152 |
@@ -493,7 +493,7 @@ public class ShopsServiceImpl extends BaseService implements IShopsService, Appl | @@ -493,7 +493,7 @@ public class ShopsServiceImpl extends BaseService implements IShopsService, Appl | ||
493 | * @param paramMap | 493 | * @param paramMap |
494 | * @return | 494 | * @return |
495 | */ | 495 | */ |
496 | - private SearchApiResult getShopsInfo(Map<String, String> paramMap) { | 496 | + public SearchApiResult getShopsInfo(Map<String, String> paramMap) { |
497 | try { | 497 | try { |
498 | logger.info("[func=getShopsInfo][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis()); | 498 | logger.info("[func=getShopsInfo][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis()); |
499 | // 1、构建SearchParam | 499 | // 1、构建SearchParam |
@@ -271,7 +271,12 @@ public class SuggestServiceImpl implements ISuggestService, ApplicationEventPubl | @@ -271,7 +271,12 @@ public class SuggestServiceImpl implements ISuggestService, ApplicationEventPubl | ||
271 | if (StringUtils.isNotEmpty(queryWord)) { | 271 | if (StringUtils.isNotEmpty(queryWord)) { |
272 | // 是否精确匹配 | 272 | // 是否精确匹配 |
273 | String accurateQuery = paramMap.get("accurate"); | 273 | String accurateQuery = paramMap.get("accurate"); |
274 | - queryBuilder = "Y".equalsIgnoreCase(accurateQuery) ? QueryBuilders.matchQuery("standardKeyword", CharUtils.standardized(queryWord)) : QueryBuilders.matchQuery("keyword.keyword_ik", queryWord); | 274 | + if ("Y".equalsIgnoreCase(accurateQuery)) { |
275 | + queryBuilder = QueryBuilders.matchQuery("standardKeyword", CharUtils.standardized(queryWord)); | ||
276 | + } else { | ||
277 | + queryBuilder = QueryBuilders.multiMatchQuery(queryWord.trim().toLowerCase(), "keyword", "keyword.keyword_lowercase", | ||
278 | + "keyword.keyword_pinyin", "keyword.keyword_jianpin", "keyword.keyword_ik"); | ||
279 | + } | ||
275 | } | 280 | } |
276 | 281 | ||
277 | searchParam.setQuery(queryBuilder); | 282 | searchParam.setQuery(queryBuilder); |
-
Please register or login to post a comment