|
|
package com.yoho.search.service.servicenew.impl;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Collections;
|
|
|
import java.util.Comparator;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Iterator;
|
|
|
import java.util.List;
|
...
|
...
|
@@ -203,7 +205,7 @@ public class AggProductListServiceImpl implements IAggProductListService, Applic |
|
|
searchParam.setFiter(searchServiceHelper.constructFilterBuilder(paramMap, null));
|
|
|
searchParam.setSize(0);
|
|
|
|
|
|
// 4、构造聚合条件[以下的写法可以让聚合支持排序]
|
|
|
// 4、构造聚合条件
|
|
|
final String firstAggName = "firstAgg";
|
|
|
String order = "sales_num:desc";
|
|
|
if (searchCommonHelper.isNeedPersonalSearch(paramMap)) {
|
...
|
...
|
@@ -212,11 +214,11 @@ public class AggProductListServiceImpl implements IAggProductListService, Applic |
|
|
order = searchSortHelper.dealSortField(order);
|
|
|
String sortField = order.split(":")[0];
|
|
|
SortOrder sortOrder = order.split(":")[1].equals("desc") ? SortOrder.DESC : SortOrder.ASC;
|
|
|
|
|
|
|
|
|
List<AbstractAggregationBuilder> list = new ArrayList<AbstractAggregationBuilder>();
|
|
|
// 4.1)构造父聚合:品牌或品类聚合【同时按子聚合的sort字段排序】
|
|
|
TermsBuilder brandAggregationBuilder = AggregationBuilders.terms(firstAggName).field("brandId").order(Terms.Order.aggregation("sort", sortOrder.equals(SortOrder.ASC)))
|
|
|
.size(pageSize);
|
|
|
.size(200+pageSize);
|
|
|
// 4.2)添加子聚合:取得分最大的值
|
|
|
brandAggregationBuilder.subAggregation(AggregationBuilders.max("sort").field(sortField));
|
|
|
// 4.3)添加孙聚合:取打分最高的一个product
|
...
|
...
|
@@ -242,7 +244,7 @@ public class AggProductListServiceImpl implements IAggProductListService, Applic |
|
|
if (!aggMaps.containsKey(firstAggName)) {
|
|
|
return searchApiResult.setData("");
|
|
|
}
|
|
|
List<Map<String, Object>> productList = this.getProductList(((MultiBucketsAggregation) aggMaps.get(firstAggName)));
|
|
|
List<Map<String, Object>> productList = this.getProductListOrderByScore(((MultiBucketsAggregation) aggMaps.get(firstAggName)), pageSize,sortField,sortOrder);
|
|
|
jsonObject = new JSONObject();
|
|
|
jsonObject.put("total", pageSize);
|
|
|
jsonObject.put("page", 1);
|
...
|
...
|
@@ -258,4 +260,96 @@ public class AggProductListServiceImpl implements IAggProductListService, Applic |
|
|
}
|
|
|
}
|
|
|
|
|
|
private List<Map<String, Object>> getProductListOrderByScore(final MultiBucketsAggregation aggregation, int viewNum, String sortField, SortOrder sortOrder) {
|
|
|
Iterator<? extends Bucket> itAgg = aggregation.getBuckets().iterator();
|
|
|
// 获取品牌聚合出来的商品
|
|
|
TopHits topHits;
|
|
|
SearchHits hits;
|
|
|
List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
|
|
|
List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();
|
|
|
while (itAgg.hasNext()) {
|
|
|
Bucket lt = itAgg.next();
|
|
|
if (lt.getAggregations().getAsMap().containsKey("product")) {
|
|
|
topHits = lt.getAggregations().get("product");
|
|
|
if (topHits != null) {
|
|
|
hits = topHits.getHits();
|
|
|
for (SearchHit hit : hits.getHits()) {
|
|
|
Map<String, Object> source = hit.getSource();
|
|
|
float _score = hit.getScore();
|
|
|
source.put("_score", _score);
|
|
|
dataList.add(source);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
dataList = this.sortListBySortField(dataList, viewNum, sortField, sortOrder);
|
|
|
try {
|
|
|
List<String> sknStr = new ArrayList<String>();
|
|
|
for (Map<String, Object> data : dataList) {
|
|
|
sknStr.add("" + data.get("productSkn"));
|
|
|
}
|
|
|
Map<String, List<Map<String, Object>>> productPricePlanMap = searchServiceHelper.searchProductPricePlan((String[]) sknStr.toArray(new String[sknStr.size()]));
|
|
|
for (Map<String, Object> m : dataList) {
|
|
|
result.add(searchServiceHelper.getProductMapWithPricePlan(m, productPricePlanMap));
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
logger.error("[func=aggProductList][Exception={}][begin={}]", e, System.currentTimeMillis());
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
private double getDouble(Object value) {
|
|
|
if (value == null) {
|
|
|
return 0;
|
|
|
}
|
|
|
if (value instanceof Float){
|
|
|
return ((Float) value).floatValue();
|
|
|
}
|
|
|
if (value instanceof Integer){
|
|
|
return ((Integer) value);
|
|
|
}
|
|
|
if (value instanceof Long){
|
|
|
return ((Long) value);
|
|
|
}
|
|
|
if (value instanceof String){
|
|
|
return Double.valueOf(value.toString());
|
|
|
}
|
|
|
if (value instanceof Double){
|
|
|
return Double.valueOf(value.toString());
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
private List<Map<String, Object>> sortListBySortField(List<Map<String, Object>> productList, int viewNum, String orderField, SortOrder sortOrder) {
|
|
|
if (productList == null || productList.isEmpty()) {
|
|
|
return new ArrayList<Map<String, Object>>();
|
|
|
}
|
|
|
// 再按照某个字段对商品排序
|
|
|
boolean isDesc = sortOrder.equals(SortOrder.DESC) ? true : false;
|
|
|
|
|
|
Collections.sort(productList, new Comparator<Map<String, Object>>() {
|
|
|
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
|
|
|
try {
|
|
|
double value1 = getDouble(o1.get(orderField));
|
|
|
double value2 = getDouble(o2.get(orderField));
|
|
|
if (value1 == value2) {
|
|
|
return 0;
|
|
|
}
|
|
|
if (isDesc) {
|
|
|
return value1 - value2 > 0 ? -1 : 1;
|
|
|
} else {
|
|
|
return value1 - value2 > 0 ? 1 : -1;
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
logger.error(e.getMessage(), e);
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
if (productList.size() > viewNum) {
|
|
|
productList = productList.subList(0, viewNum);
|
|
|
}
|
|
|
return productList;
|
|
|
}
|
|
|
|
|
|
} |
...
|
...
|
|