Showing
1 changed file
with
98 additions
and
4 deletions
1 | package com.yoho.search.service.servicenew.impl; | 1 | package com.yoho.search.service.servicenew.impl; |
2 | 2 | ||
3 | import java.util.ArrayList; | 3 | import java.util.ArrayList; |
4 | +import java.util.Collections; | ||
5 | +import java.util.Comparator; | ||
4 | import java.util.HashMap; | 6 | import java.util.HashMap; |
5 | import java.util.Iterator; | 7 | import java.util.Iterator; |
6 | import java.util.List; | 8 | import java.util.List; |
@@ -203,7 +205,7 @@ public class AggProductListServiceImpl implements IAggProductListService, Applic | @@ -203,7 +205,7 @@ public class AggProductListServiceImpl implements IAggProductListService, Applic | ||
203 | searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null)); | 205 | searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null)); |
204 | searchParam.setSize(0); | 206 | searchParam.setSize(0); |
205 | 207 | ||
206 | - // 4、构造聚合条件[以下的写法可以让聚合支持排序] | 208 | + // 4、构造聚合条件 |
207 | final String firstAggName = "firstAgg"; | 209 | final String firstAggName = "firstAgg"; |
208 | String order = "sales_num:desc"; | 210 | String order = "sales_num:desc"; |
209 | if (searchCommonHelper.isNeedPersonalSearch(paramMap)) { | 211 | if (searchCommonHelper.isNeedPersonalSearch(paramMap)) { |
@@ -212,11 +214,11 @@ public class AggProductListServiceImpl implements IAggProductListService, Applic | @@ -212,11 +214,11 @@ public class AggProductListServiceImpl implements IAggProductListService, Applic | ||
212 | order = searchSortHelper.dealSortField(order); | 214 | order = searchSortHelper.dealSortField(order); |
213 | String sortField = order.split(":")[0]; | 215 | String sortField = order.split(":")[0]; |
214 | SortOrder sortOrder = order.split(":")[1].equals("desc") ? SortOrder.DESC : SortOrder.ASC; | 216 | SortOrder sortOrder = order.split(":")[1].equals("desc") ? SortOrder.DESC : SortOrder.ASC; |
215 | - | 217 | + |
216 | List<AbstractAggregationBuilder> list = new ArrayList<AbstractAggregationBuilder>(); | 218 | List<AbstractAggregationBuilder> list = new ArrayList<AbstractAggregationBuilder>(); |
217 | // 4.1)构造父聚合:品牌或品类聚合【同时按子聚合的sort字段排序】 | 219 | // 4.1)构造父聚合:品牌或品类聚合【同时按子聚合的sort字段排序】 |
218 | TermsBuilder brandAggregationBuilder = AggregationBuilders.terms(firstAggName).field("brandId").order(Terms.Order.aggregation("sort", sortOrder.equals(SortOrder.ASC))) | 220 | TermsBuilder brandAggregationBuilder = AggregationBuilders.terms(firstAggName).field("brandId").order(Terms.Order.aggregation("sort", sortOrder.equals(SortOrder.ASC))) |
219 | - .size(pageSize); | 221 | + .size(200+pageSize); |
220 | // 4.2)添加子聚合:取得分最大的值 | 222 | // 4.2)添加子聚合:取得分最大的值 |
221 | brandAggregationBuilder.subAggregation(AggregationBuilders.max("sort").field(sortField)); | 223 | brandAggregationBuilder.subAggregation(AggregationBuilders.max("sort").field(sortField)); |
222 | // 4.3)添加孙聚合:取打分最高的一个product | 224 | // 4.3)添加孙聚合:取打分最高的一个product |
@@ -242,7 +244,7 @@ public class AggProductListServiceImpl implements IAggProductListService, Applic | @@ -242,7 +244,7 @@ public class AggProductListServiceImpl implements IAggProductListService, Applic | ||
242 | if (!aggMaps.containsKey(firstAggName)) { | 244 | if (!aggMaps.containsKey(firstAggName)) { |
243 | return searchApiResult.setData(""); | 245 | return searchApiResult.setData(""); |
244 | } | 246 | } |
245 | - List<Map<String, Object>> productList = this.getProductList(((MultiBucketsAggregation) aggMaps.get(firstAggName))); | 247 | + List<Map<String, Object>> productList = this.getProductListOrderByScore(((MultiBucketsAggregation) aggMaps.get(firstAggName)), pageSize,sortField,sortOrder); |
246 | jsonObject = new JSONObject(); | 248 | jsonObject = new JSONObject(); |
247 | jsonObject.put("total", pageSize); | 249 | jsonObject.put("total", pageSize); |
248 | jsonObject.put("page", 1); | 250 | jsonObject.put("page", 1); |
@@ -258,4 +260,96 @@ public class AggProductListServiceImpl implements IAggProductListService, Applic | @@ -258,4 +260,96 @@ public class AggProductListServiceImpl implements IAggProductListService, Applic | ||
258 | } | 260 | } |
259 | } | 261 | } |
260 | 262 | ||
263 | + private List<Map<String, Object>> getProductListOrderByScore(final MultiBucketsAggregation aggregation, int viewNum, String sortField, SortOrder sortOrder) { | ||
264 | + Iterator<? extends Bucket> itAgg = aggregation.getBuckets().iterator(); | ||
265 | + // 获取品牌聚合出来的商品 | ||
266 | + TopHits topHits; | ||
267 | + SearchHits hits; | ||
268 | + List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(); | ||
269 | + List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>(); | ||
270 | + while (itAgg.hasNext()) { | ||
271 | + Bucket lt = itAgg.next(); | ||
272 | + if (lt.getAggregations().getAsMap().containsKey("product")) { | ||
273 | + topHits = lt.getAggregations().get("product"); | ||
274 | + if (topHits != null) { | ||
275 | + hits = topHits.getHits(); | ||
276 | + for (SearchHit hit : hits.getHits()) { | ||
277 | + Map<String, Object> source = hit.getSource(); | ||
278 | + float _score = hit.getScore(); | ||
279 | + source.put("_score", _score); | ||
280 | + dataList.add(source); | ||
281 | + } | ||
282 | + } | ||
283 | + } | ||
284 | + } | ||
285 | + dataList = this.sortListBySortField(dataList, viewNum, sortField, sortOrder); | ||
286 | + try { | ||
287 | + List<String> sknStr = new ArrayList<String>(); | ||
288 | + for (Map<String, Object> data : dataList) { | ||
289 | + sknStr.add("" + data.get("productSkn")); | ||
290 | + } | ||
291 | + Map<String, List<Map<String, Object>>> productPricePlanMap = searchServiceHelper.searchProductPricePlan((String[]) sknStr.toArray(new String[sknStr.size()])); | ||
292 | + for (Map<String, Object> m : dataList) { | ||
293 | + result.add(searchServiceHelper.getProductMapWithPricePlan(m, productPricePlanMap)); | ||
294 | + } | ||
295 | + } catch (Exception e) { | ||
296 | + logger.error("[func=aggProductList][Exception={}][begin={}]", e, System.currentTimeMillis()); | ||
297 | + } | ||
298 | + return result; | ||
299 | + } | ||
300 | + | ||
301 | + private double getDouble(Object value) { | ||
302 | + if (value == null) { | ||
303 | + return 0; | ||
304 | + } | ||
305 | + if (value instanceof Float){ | ||
306 | + return ((Float) value).floatValue(); | ||
307 | + } | ||
308 | + if (value instanceof Integer){ | ||
309 | + return ((Integer) value); | ||
310 | + } | ||
311 | + if (value instanceof Long){ | ||
312 | + return ((Long) value); | ||
313 | + } | ||
314 | + if (value instanceof String){ | ||
315 | + return Double.valueOf(value.toString()); | ||
316 | + } | ||
317 | + if (value instanceof Double){ | ||
318 | + return Double.valueOf(value.toString()); | ||
319 | + } | ||
320 | + return 0; | ||
321 | + } | ||
322 | + | ||
323 | + private List<Map<String, Object>> sortListBySortField(List<Map<String, Object>> productList, int viewNum, String orderField, SortOrder sortOrder) { | ||
324 | + if (productList == null || productList.isEmpty()) { | ||
325 | + return new ArrayList<Map<String, Object>>(); | ||
326 | + } | ||
327 | + // 再按照某个字段对商品排序 | ||
328 | + boolean isDesc = sortOrder.equals(SortOrder.DESC) ? true : false; | ||
329 | + | ||
330 | + Collections.sort(productList, new Comparator<Map<String, Object>>() { | ||
331 | + public int compare(Map<String, Object> o1, Map<String, Object> o2) { | ||
332 | + try { | ||
333 | + double value1 = getDouble(o1.get(orderField)); | ||
334 | + double value2 = getDouble(o2.get(orderField)); | ||
335 | + if (value1 == value2) { | ||
336 | + return 0; | ||
337 | + } | ||
338 | + if (isDesc) { | ||
339 | + return value1 - value2 > 0 ? -1 : 1; | ||
340 | + } else { | ||
341 | + return value1 - value2 > 0 ? 1 : -1; | ||
342 | + } | ||
343 | + } catch (Exception e) { | ||
344 | + logger.error(e.getMessage(), e); | ||
345 | + return -1; | ||
346 | + } | ||
347 | + } | ||
348 | + }); | ||
349 | + if (productList.size() > viewNum) { | ||
350 | + productList = productList.subList(0, viewNum); | ||
351 | + } | ||
352 | + return productList; | ||
353 | + } | ||
354 | + | ||
261 | } | 355 | } |
-
Please register or login to post a comment