Authored by hugufei

Merge branch 'master' into hongren

... ... @@ -64,19 +64,6 @@ public class BrandController {
}
/**
* 获取最新上架的商品列表【已过滤相同的品牌】
*
* @param request
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "/new-shelve")
@ResponseBody
public SearchApiResult aggProductsByBrandId(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return brandService.aggProductsByBrandId(paramMap);
}
/**
* 获取不同品牌的商品列表【按order参数对商品排序】【参数要传brand】
*
* @param request
... ...
... ... @@ -29,8 +29,6 @@ public class ProductListController {
private IProductListService productListService;
@Autowired
private ProductListSwitchService productListSwitchService;
@Autowired
private FuzzySceneProductListService fuzzySceneProductListService;
/**
* 获取商品列表-支持个性化降级
... ... @@ -42,11 +40,7 @@ public class ProductListController {
@ResponseBody
public SearchApiResult productList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
if(StringUtils.isNotBlank(MapUtils.getString(paramMap,"query"))){
return fuzzySceneProductListService.productList(paramMap);
}else{
return productListSwitchService.productList(paramMap);
}
return productListSwitchService.productList(paramMap);
}
/**
... ...
... ... @@ -37,4 +37,16 @@ public class RobotQuestionController {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return robotQuestionService.robotQuestion(paramMap);
}
/**
* 按id查询当前ES中的数据
*
* @param id
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "/queryRobotQuestionById")
@ResponseBody
public SearchApiResult queryRobotQuestionById(String id) {
return robotQuestionService.queryRobotQuestionById(id);
}
}
... ...
... ... @@ -4,6 +4,7 @@ import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.yoho.search.service.service.IWebNewShelveService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
... ... @@ -20,6 +21,8 @@ public class WebProductListController {
@Autowired
private WebProductListService webProductListService;
@Autowired
private IWebNewShelveService webNewShelveService;
/**
* pc-商品列表
... ... @@ -33,4 +36,29 @@ public class WebProductListController {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return webProductListService.webProductList(paramMap);
}
/**
* pc-首页最新上架
*
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "/new-shelve")
@ResponseBody
public SearchApiResult webNewShelve(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return webNewShelveService.webNewShelveProductList(paramMap);
}
/**
* pc-首页最新上架
*
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "/web/newShelveBatch")
@ResponseBody
public SearchApiResult webNewShelveBatch(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return webNewShelveService.webNewShelveBatchProductList(paramMap);
}
}
... ...
... ... @@ -29,187 +29,186 @@ import com.yoho.search.service.aggregations.common.SimpleFieldAgg;
public class AggCommonHelper {
private static final Logger logger = LoggerFactory.getLogger(AggCommonHelper.class);
public static List<Integer> getIdsFromAggMaps(Map<String, Aggregation> aggMaps, String aggName) {
if (!aggMaps.containsKey(aggName)) {
return new ArrayList<>();
}
MultiBucketsAggregation aggregation = (MultiBucketsAggregation) aggMaps.get(aggName);
List<Integer> results = new ArrayList<Integer>();
Iterator<? extends MultiBucketsAggregation.Bucket> iterator = aggregation.getBuckets().iterator();
while (iterator.hasNext()) {
MultiBucketsAggregation.Bucket bucket = iterator.next();
if (StringUtils.isNumeric(bucket.getKeyAsString())) {
results.add(Integer.valueOf(bucket.getKeyAsString()));
}
}
return results;
}
/**
* 获取tophit的聚合结果
*
* @param simpleFieldAggs
* @param topHitOrder
* @param topHitFieldCount
* @return
*/
public static AbstractAggregationBuilder<?> getTopHitAggregation(List<SimpleFieldAgg> simpleFieldAggs, String topHitOrder, int topHitCount) {
int length = simpleFieldAggs.size();
FieldSortOrder fieldSortOrder = new FieldSortOrder(topHitOrder);
SortBuilder<?> sortBuilder = null;
if (fieldSortOrder.isScoreOrder()) {
sortBuilder = SortBuilders.scoreSort();
} else {
sortBuilder = SortBuilders.fieldSort(fieldSortOrder.getSortField()).order(fieldSortOrder.getSortOrder());
}
AbstractAggregationBuilder<?> result = null;
for (int i = length - 1; i >= 0; i--) {
SimpleFieldAgg simpleFieldAgg = simpleFieldAggs.get(i);
TermsAggregationBuilder temp = AggregationBuilders.terms(simpleFieldAgg.getAggName()).field(simpleFieldAgg.getEsField()).size(simpleFieldAgg.getBucketCount());
// 如果是最小层面的聚合,则加上tophit的聚合
if (result == null) {
if (topHitCount > 0) {
temp.subAggregation(AggregationBuilders.max("sort").field(fieldSortOrder.getSortField()));
temp.subAggregation(AggregationBuilders.topHits("topHit").sort(sortBuilder).size(topHitCount));
}
result = temp;
} else {
result = temp.subAggregation(result);
}
}
return result;
}
/**
* 获取聚合出来的商品列表,并按特定顺序截取
*
* @param aggregation
* @param viewNum
* @param sortField
* @param sortOrder
* @return
*/
public static List<Map<String, Object>> getTopHitList(Map<String, Aggregation> aggMaps, List<SimpleFieldAgg> simpleFieldAggs, String topHitOrder, int totalCount) {
List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
getTopHitResults(results, aggMaps, simpleFieldAggs, 0);
results = sortListBySortField(results, topHitOrder, totalCount);
return results;
}
private static void getTopHitResults(List<Map<String, Object>> results, Map<String, Aggregation> aggMaps, List<SimpleFieldAgg> simpleFieldAggs, int index) {
try {
String aggName = simpleFieldAggs.get(index++).getAggName();
if (!aggMaps.containsKey(aggName)) {
return;
}
List<? extends Bucket> bucketList = ((MultiBucketsAggregation) aggMaps.get(aggName)).getBuckets();
if (bucketList.isEmpty()) {
return;
}
for (Bucket bucket : bucketList) {
Map<String, Aggregation> aggMap = bucket.getAggregations().getAsMap();
if (aggMap.containsKey("topHit")) {
TopHits topHits = bucket.getAggregations().get("topHit");
if (topHits != null) {
SearchHits hits = topHits.getHits();
for (SearchHit hit : hits.getHits()) {
Map<String, Object> source = hit.getSource();
float _score = hit.getScore();
source.put("_score", _score);
results.add(source);
}
}
} else {
getTopHitResults(results, aggMap, simpleFieldAggs, index);
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
private static List<Map<String, Object>> sortListBySortField(List<Map<String, Object>> productList, String topHitOrder, int viewNum) {
if (productList == null || productList.isEmpty()) {
return new ArrayList<Map<String, Object>>();
}
// 再按照某个字段对商品排序
FieldSortOrder fieldSortOrder = new FieldSortOrder(topHitOrder);
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(fieldSortOrder.getSortField()));
double value2 = getDouble(o2.get(fieldSortOrder.getSortField()));
if (fieldSortOrder.isDesc()) {
return value1 > value2 ? -1 : value1 < value2 ? 1 : 0;
} else {
return value1 > value2 ? 1 : value1 < value2 ? -1 : 0;
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
return -1;
}
}
});
if (productList.size() > viewNum) {
productList = CollectionUtils.safeSubList(productList, 0, viewNum);
}
return productList;
}
private static double getDouble(Object value) {
try {
if (value == null) {
return 0;
}
return Double.parseDouble(value.toString());
} catch (Exception e) {
return 0;
}
}
/**
* 按聚合的key获取聚合出来的商品列表[目前只支持一个field,多重field的话,key不好处理]
*
* @param aggregation
* @param viewNum
* @param sortField
* @param sortOrder
* @return
*/
public static List<KeyTopHitModel> getTopHitListGroupByKey(Map<String, Aggregation> aggMaps, SimpleFieldAgg simpleFieldAgg) {
String aggName = simpleFieldAgg.getAggName();
if (!aggMaps.containsKey(aggName)) {
return new ArrayList<KeyTopHitModel>();
}
List<? extends Bucket> bucketList = ((MultiBucketsAggregation) aggMaps.get(aggName)).getBuckets();
if (bucketList.isEmpty()) {
return new ArrayList<KeyTopHitModel>();
}
List<KeyTopHitModel> results = new ArrayList<KeyTopHitModel>();
for (Bucket bucket : bucketList) {
String key = bucket.getKeyAsString();
long count = bucket.getDocCount();
List<Map<String, Object>> topHitList = new ArrayList<Map<String, Object>>();
Map<String, Aggregation> aggMap = bucket.getAggregations().getAsMap();
if (aggMap.containsKey("topHit")) {
TopHits topHits = bucket.getAggregations().get("topHit");
if (topHits != null) {
SearchHits hits = topHits.getHits();
for (SearchHit hit : hits.getHits()) {
Map<String, Object> source = hit.getSource();
float _score = hit.getScore();
source.put("_score", _score);
topHitList.add(source);
}
}
}
KeyTopHitModel keyTopHitModel = new KeyTopHitModel(key, count, topHitList);
results.add(keyTopHitModel);
}
return results;
}
private static final Logger logger = LoggerFactory.getLogger(AggCommonHelper.class);
/**
* 从TopHits中获取_source
*
* @param topHits
* @return
*/
public static List<Map<String, Object>> getTopHitResultsWithScore(TopHits topHits) {
List<Map<String, Object>> topHitList = new ArrayList<>();
if (topHits == null) {
return topHitList;
}
SearchHits hits = topHits.getHits();
for (SearchHit hit : hits.getHits()) {
Map<String, Object> source = hit.getSource();
float _score = hit.getScore();
source.put("_score", _score);
topHitList.add(source);
}
return topHitList;
}
public static List<Integer> getIdsFromAggMaps(Map<String, Aggregation> aggMaps, String aggName) {
if (!aggMaps.containsKey(aggName)) {
return new ArrayList<>();
}
MultiBucketsAggregation aggregation = (MultiBucketsAggregation) aggMaps.get(aggName);
List<Integer> results = new ArrayList<Integer>();
Iterator<? extends MultiBucketsAggregation.Bucket> iterator = aggregation.getBuckets().iterator();
while (iterator.hasNext()) {
MultiBucketsAggregation.Bucket bucket = iterator.next();
if (StringUtils.isNumeric(bucket.getKeyAsString())) {
results.add(Integer.valueOf(bucket.getKeyAsString()));
}
}
return results;
}
/**
* 获取tophit的聚合结果
*
* @param simpleFieldAggs
* @param topHitOrder
* @param topHitCount
* @return
*/
public static AbstractAggregationBuilder<?> getTopHitAggregation(List<SimpleFieldAgg> simpleFieldAggs, String topHitOrder, int topHitCount) {
int length = simpleFieldAggs.size();
FieldSortOrder fieldSortOrder = new FieldSortOrder(topHitOrder);
SortBuilder<?> sortBuilder = null;
if (fieldSortOrder.isScoreOrder()) {
sortBuilder = SortBuilders.scoreSort();
} else {
sortBuilder = SortBuilders.fieldSort(fieldSortOrder.getSortField()).order(fieldSortOrder.getSortOrder());
}
AbstractAggregationBuilder<?> result = null;
for (int i = length - 1; i >= 0; i--) {
SimpleFieldAgg simpleFieldAgg = simpleFieldAggs.get(i);
TermsAggregationBuilder temp = AggregationBuilders.terms(simpleFieldAgg.getAggName()).field(simpleFieldAgg.getEsField()).size(simpleFieldAgg.getBucketCount());
// 如果是最小层面的聚合,则加上tophit的聚合
if (result == null) {
if (topHitCount > 0) {
temp.subAggregation(AggregationBuilders.max("sort").field(fieldSortOrder.getSortField()));
temp.subAggregation(AggregationBuilders.topHits("topHit").sort(sortBuilder).size(topHitCount));
}
result = temp;
} else {
result = temp.subAggregation(result);
}
}
return result;
}
/**
* 获取聚合出来的商品列表,并按特定顺序截取
*/
public static List<Map<String, Object>> getTopHitList(Map<String, Aggregation> aggMaps, List<SimpleFieldAgg> simpleFieldAggs, String topHitOrder, int totalCount) {
List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
getTopHitResults(results, aggMaps, simpleFieldAggs, 0);
results = sortListBySortField(results, topHitOrder, totalCount);
return results;
}
private static void getTopHitResults(List<Map<String, Object>> results, Map<String, Aggregation> aggMaps, List<SimpleFieldAgg> simpleFieldAggs, int index) {
try {
String aggName = simpleFieldAggs.get(index++).getAggName();
if (!aggMaps.containsKey(aggName)) {
return;
}
List<? extends Bucket> bucketList = ((MultiBucketsAggregation) aggMaps.get(aggName)).getBuckets();
if (bucketList.isEmpty()) {
return;
}
for (Bucket bucket : bucketList) {
Map<String, Aggregation> aggMap = bucket.getAggregations().getAsMap();
if (aggMap.containsKey("topHit")) {
TopHits topHits = bucket.getAggregations().get("topHit");
List<Map<String, Object>> topHitList = getTopHitResultsWithScore(topHits);
results.addAll(topHitList);
} else {
getTopHitResults(results, aggMap, simpleFieldAggs, index);
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
private static List<Map<String, Object>> sortListBySortField(List<Map<String, Object>> productList, String topHitOrder, int viewNum) {
if (productList == null || productList.isEmpty()) {
return new ArrayList<>();
}
// 再按照某个字段对商品排序
FieldSortOrder fieldSortOrder = new FieldSortOrder(topHitOrder);
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(fieldSortOrder.getSortField()));
double value2 = getDouble(o2.get(fieldSortOrder.getSortField()));
if (fieldSortOrder.isDesc()) {
return value1 > value2 ? -1 : value1 < value2 ? 1 : 0;
} else {
return value1 > value2 ? 1 : value1 < value2 ? -1 : 0;
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
return -1;
}
}
});
if (productList.size() > viewNum) {
productList = CollectionUtils.safeSubList(productList, 0, viewNum);
}
return productList;
}
private static double getDouble(Object value) {
try {
if (value == null) {
return 0;
}
return Double.parseDouble(value.toString());
} catch (Exception e) {
return 0;
}
}
/**
* 按聚合的key获取聚合出来的商品列表[目前只支持一个field,多重field的话,key不好处理]
*
* @return
*/
public static List<KeyTopHitModel> getTopHitListGroupByKey(Map<String, Aggregation> aggMaps, SimpleFieldAgg simpleFieldAgg) {
String aggName = simpleFieldAgg.getAggName();
if (!aggMaps.containsKey(aggName)) {
return new ArrayList<>();
}
List<? extends Bucket> bucketList = ((MultiBucketsAggregation) aggMaps.get(aggName)).getBuckets();
if (bucketList.isEmpty()) {
return new ArrayList<>();
}
List<KeyTopHitModel> results = new ArrayList<KeyTopHitModel>();
for (Bucket bucket : bucketList) {
String key = bucket.getKeyAsString();
long count = bucket.getDocCount();
List<Map<String, Object>> topHitList = new ArrayList<>();
Map<String, Aggregation> aggMap = bucket.getAggregations().getAsMap();
if (aggMap.containsKey("topHit")) {
TopHits topHits = bucket.getAggregations().get("topHit");
List<Map<String, Object>> tempTopHitList = getTopHitResultsWithScore(topHits);
topHitList.addAll(tempTopHitList);
}
KeyTopHitModel keyTopHitModel = new KeyTopHitModel(key, count, topHitList);
results.add(keyTopHitModel);
}
return results;
}
}
... ...
package com.yoho.search.service.helper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation.Bucket;
import org.elasticsearch.search.aggregations.metrics.tophits.TopHits;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.yoho.search.base.utils.CollectionUtils;
import com.yoho.search.service.base.index.ProductIndexBaseService;
@Component
public class AggProductListHelper {
@Autowired
private ProductIndexBaseService productIndexBaseService;
/**
* 获取聚合出来的商品列表
*
* @param aggregation
* @return
*/
public List<Map<String, Object>> getProductListFromAggregation(final MultiBucketsAggregation aggregation) {
Iterator<? extends Bucket> itAgg = aggregation.getBuckets().iterator();
List<Map<String, Object>> productEsSourceList = new ArrayList<Map<String, Object>>();
while (itAgg.hasNext()) {
Bucket lt = itAgg.next();
if (lt.getAggregations().getAsMap().containsKey("product")) {
TopHits topHits = lt.getAggregations().get("product");
if (topHits != null) {
SearchHits hits = topHits.getHits();
for (SearchHit hit : hits.getHits()) {
productEsSourceList.add(hit.getSource());
}
}
}
}
if (productEsSourceList == null || productEsSourceList.isEmpty()) {
return new ArrayList<Map<String, Object>>();
}
return productIndexBaseService.getProductListWithPricePlan(productEsSourceList);
}
/**
* 获取聚合出来的商品列表,并按特定顺序截取
*
* @param aggregation
* @param viewNum
* @param sortField
* @param sortOrder
* @return
*/
public List<Map<String, Object>> getProductListFromAggregation(final MultiBucketsAggregation aggregation, int viewNum, String sortField, SortOrder sortOrder) {
Iterator<? extends Bucket> itAgg = aggregation.getBuckets().iterator();
// 获取品牌聚合出来的商品
List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();
while (itAgg.hasNext()) {
Bucket lt = itAgg.next();
if (lt.getAggregations().getAsMap().containsKey("product")) {
TopHits topHits = lt.getAggregations().get("product");
if (topHits == null) {
continue;
}
SearchHits 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);
return productIndexBaseService.getProductListWithPricePlan(dataList);
}
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 == SortOrder.DESC ? true : false;
Collections.sort(productList, new Comparator<Map<String, Object>>() {
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
double value1 = getDouble(o1.get(orderField));
double value2 = getDouble(o2.get(orderField));
if (isDesc) {
return value1 > value2 ? -1 : value1 < value2 ? 1 : 0;
} else {
return value1 > value2 ? 1 : value1 < value2 ? -1 : 0;
}
}
});
if (productList.size() > viewNum) {
productList = CollectionUtils.safeSubList(productList, 0, viewNum);
}
return productList;
}
private double getDouble(Object value) {
try {
return Double.parseDouble(value.toString());
} catch (Exception e) {
return 0;
}
}
}
... ... @@ -9,6 +9,7 @@ import java.util.Set;
import javax.annotation.PostConstruct;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.models.SearchSort;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
... ... @@ -246,4 +247,15 @@ public class SearchSortHelper {
return sortBuilders;
}
public SearchSort buildSearchSort(Map<String, String> paramMap,String defaultSort){
String sortField = this.getLegalOrder(paramMap);
if (StringUtils.isBlank(sortField)) {
sortField = defaultSort;
}
String[] sortParts = sortField.split(":");
String realSortField = sortParts[0];
String realSortType = sortParts[1];
return new SearchSort(realSortField,"asc".equalsIgnoreCase(realSortType)?SortOrder.ASC:SortOrder.DESC);
}
}
... ...
... ... @@ -2,6 +2,7 @@ package com.yoho.search.service.list;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.SearchPageIdDefine;
import com.yoho.search.common.cache.SearchCacheMatchLogger;
import com.yoho.search.common.cache.model.SearchCache;
import com.yoho.search.core.es.model.SearchParam;
... ... @@ -9,6 +10,7 @@ import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.ProductListSortService;
import com.yoho.search.service.base.SearchCommonService;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.base.index.ProductIndexBaseService;
import com.yoho.search.service.helper.SearchCommonHelper;
import com.yoho.search.service.helper.SearchParamHelper;
... ... @@ -54,6 +56,9 @@ public class FuzzySceneProductListService extends AbstractCacheAbleService {
*/
public SearchApiResult productList(Map<String, String> paramMap) {
try {
// 0)定义页面为模糊搜索的页面
paramMap.put(SearchRequestParams.PARAM_SEARCH_PAGEID, SearchPageIdDefine.PAGE_ID_SEARCH);
// 1)构造搜索参数
SearchParam searchParam = this.buildProductListSearchParam(paramMap);
... ...
... ... @@ -28,6 +28,8 @@ public class ProductListSwitchService {
private SceneRecallProductListService sceneRecallProductListService;
@Autowired
private SearchCommonHelper searchCommonHelper;
@Autowired
private FuzzySceneProductListService fuzzySceneProductListService;
/**
* 各商品列表的统一入口
... ... @@ -36,7 +38,7 @@ public class ProductListSwitchService {
* @return
*/
public SearchApiResult productList(Map<String, String> paramMap) {
// 0)参数校验
// 1、参数校验
int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
if (page < 1 || pageSize < 0 || page * pageSize > 1000000) {
... ... @@ -47,25 +49,34 @@ public class ProductListSwitchService {
}
paramMap = searchSortHelper.checkAndFixOrder(paramMap);
// 1、如果order合法,则直接走非个性化接口
// 2、传了order,则直接走非个性化接口
if (!searchCommonHelper.isOrderEmpty(paramMap)) {
return defaultProductListService.productListNotPersional(paramMap);
}
// 2、没传order,没传uid和udid,走默认打分的逻辑
if (searchCommonHelper.isOrderEmpty(paramMap) && !searchCommonHelper.hasUid(paramMap) && !searchCommonHelper.hasUdid(paramMap)) {
// 3、如果带了query,则走模糊搜索的逻辑
if (StringUtils.isNotBlank(MapUtils.getString(paramMap, "query"))) {
return fuzzySceneProductListService.productList(paramMap);
}
// 4、没传uid和udid,走默认打分的逻辑
if (!searchCommonHelper.hasUid(paramMap) && !searchCommonHelper.hasUdid(paramMap)) {
return defaultProductListService.productListForDefaultPersional(paramMap);
}
// 3、个性化时根据开关,决定是否使用高性能的场景-双11专用
// 5、个性化时根据开关,决定是否使用高性能的场景-双11专用
boolean perfamanceStrategyOpen = searchDynamicConfigService.searchPersionalPerfamanceStrategyOpen();
if (perfamanceStrategyOpen) {
return performanceRecallProductListService.productList(paramMap);
}
// 4、是否使用新的召回策略
// 6、是否使用新的召回策略
boolean searchPersionalNewStrategyOpen = searchDynamicConfigService.searchPersionalNewStrategyOpen();
if (searchPersionalNewStrategyOpen) {
return sceneRecallProductListService.recallProductList(paramMap);
}
// 5、默认-使用向量版本的个性化方案
// 7、默认-使用向量版本的个性化方案
return defaultProductListService.productListForDefaultPersional(paramMap);
}
... ...
... ... @@ -14,6 +14,7 @@ import com.yoho.search.models.SearchApiResult;
import com.yoho.search.models.SearchSort;
import com.yoho.search.service.base.SearchCommonService;
import com.yoho.search.service.base.index.ProductIndexBaseService;
import com.yoho.search.service.helper.AggCommonHelper;
import com.yoho.search.service.helper.SearchCommonHelper;
import com.yoho.search.service.helper.SearchParamHelper;
import com.yoho.search.service.helper.SearchSortHelper;
... ... @@ -207,7 +208,7 @@ public class AggProductListService implements ApplicationEventPublisherAware {
* 【父聚合的字段名称】
* @param firstAggBucketCount
* 【父聚合的桶大小】
* @param aggOrderSearchSort
* @param aggSort
* 【聚合排序规则,即按什么排序推荐】
* @param secondSearchSort
* 【次要排序条件,即最终商品按什么排序】
... ... @@ -291,15 +292,7 @@ public class AggProductListService implements ApplicationEventPublisherAware {
Bucket lt = itAgg.next();
if (lt.getAggregations().getAsMap().containsKey("product")) {
TopHits topHits = lt.getAggregations().get("product");
if (topHits != null) {
SearchHits hits = topHits.getHits();
for (SearchHit hit : hits.getHits()) {
Map<String, Object> source = hit.getSource();
float _score = hit.getScore();
source.put("_score", _score);
productList.add(source);
}
}
productList.addAll(AggCommonHelper.getTopHitResultsWithScore(topHits));
}
}
return productList;
... ...
package com.yoho.search.service.scene;
import java.util.List;
import java.util.Map;
import java.util.*;
import com.alibaba.fastjson.JSONArray;
import com.yoho.error.event.SearchEvent;
import com.yoho.search.base.utils.EventReportEnum;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.common.cache.SearchCacheMatchLogger;
import com.yoho.search.core.es.utils.IgnoreSomeException;
import com.yoho.search.models.SearchSort;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.tophits.TopHits;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -168,4 +186,13 @@ public class WebProductListService extends AbstractCacheAbleService {
return searchDynamicConfigService.isSearchSuggestionTipsOpen();
}
/**
* pc的商品列表页
*
* @param paramMap
* @return
*/
}
... ...
... ... @@ -49,14 +49,6 @@ public interface IBrandService {
public SearchApiResult groupBrands(Map<String, String> paramMap);
/**
* 聚合不同品牌的最新商品
*
* @param paramMap
* @return
*/
public SearchApiResult aggProductsByBrandId(Map<String, String> paramMap);
/**
* 获取不同品牌的商品列表【按order参数对商品排序】【参数要传brand】
*
* @param paramMap
... ...
... ... @@ -15,4 +15,12 @@ public interface IRobotQuestionService {
* @return
*/
SearchApiResult robotQuestion(Map<String, String> paramMap);
/**
* 按id查询ES中的数据
* @param id
* @return
*/
SearchApiResult queryRobotQuestionById(String id);
}
... ...
package com.yoho.search.service.service;
import com.yoho.search.models.SearchApiResult;
import java.util.Map;
public interface IWebNewShelveService {
/**
* 聚合不同品牌的最新商品
*
* @param paramMap
* @return
*/
public SearchApiResult webNewShelveProductList(Map<String, String> paramMap);
/**
* 聚合不同品牌的最新商品
*
* @param paramMap
* @return
*/
public SearchApiResult webNewShelveBatchProductList(Map<String, String> paramMap);
}
... ...
... ... @@ -313,101 +313,6 @@ public class BrandServiceImpl extends AbstractCacheAbleService implements IBrand
}
}
@Override
public SearchApiResult aggProductsByBrandId(Map<String, String> paramMap) {
try {
logger.info("[func=aggProductsByBrandId][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());
// 1、参数校验
String sortField = searchSortHelper.getLegalOrder(paramMap);
if (StringUtils.isBlank(sortField)) {
sortField = "shelveTime:desc";
}
String[] sortParts = sortField.split(":");
String realSortField = sortParts[0];
String realSortType = sortParts[1];
// 2、构造查询条件
SearchParam searchParam = searchParamHelper.buildDefault(paramMap);
searchParam.setSize(0);
// 3、获取要取的品牌商品数量
int viewNum = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
if (viewNum > 100) {
viewNum = 100;
}
// 4、构造聚合条件
List<AbstractAggregationBuilder<?>> list = new ArrayList<AbstractAggregationBuilder<?>>();
boolean isAscOrder = SortOrder.ASC.toString().equalsIgnoreCase(realSortType);
// 4.1)构造父聚合:品牌聚合【同时按子聚合的sort字段排序】
TermsAggregationBuilder brandAggregationBuilder = AggregationBuilders.terms("brandAgg").field(ProductIndexEsField.brandId)
.order(Terms.Order.aggregation("sort", isAscOrder)).size(viewNum);
// 4.2)添加子聚合:sort值为sortFieldName的最大值或最小值,给父聚合排序用
if (isAscOrder) {
brandAggregationBuilder.subAggregation(AggregationBuilders.min("sort").field(realSortField));
} else {
brandAggregationBuilder.subAggregation(AggregationBuilders.max("sort").field(realSortField));
}
// 4.3)添加孙聚合:按sort取一个product
brandAggregationBuilder.subAggregation(AggregationBuilders.topHits("product")
.sort(SortBuilders.fieldSort(realSortField).order(isAscOrder ? SortOrder.ASC : SortOrder.DESC)).size(1));
list.add(brandAggregationBuilder);
searchParam.setAggregationBuilders(list);
// 5、构造返回结果
SearchApiResult searchApiResult = new SearchApiResult().setMessage("new-shelve list");
// 6、先从缓存中获取,如果能取到,则直接返回
JSONArray jsonArray = searchCacheService.getJSONArrayFromCache(this.searchCache, ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
if (jsonArray != null) {
SearchCacheMatchLogger.doSearchCacheMatchLog("/new-shelve.json", paramMap);
return searchApiResult.setData(jsonArray);
}
// 7、执行搜索,并构造返回结果
final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
if (searchResult == null || searchResult.getAggMaps() == null) {
return searchApiResult.setData("");
}
Map<String, Aggregation> aggMaps = searchResult.getAggMaps();
if (!aggMaps.containsKey("brandAgg")) {
return searchApiResult.setData("");
}
JSONArray productList = this.getNewShelveResponseMap(((MultiBucketsAggregation) aggMaps.get("brandAgg")));
searchCacheService.addJSONArrayToCache(this.searchCache, indexName, searchParam, productList);
return searchApiResult.setData(productList);
} catch (Exception e) {
publisher.publishEvent(new SearchEvent(EventReportEnum.SEARCHCONTROLLER_NEW_SHELVE.getEventName(), EventReportEnum.SEARCHCONTROLLER_NEW_SHELVE.getFunctionName(),
EventReportEnum.SEARCHCONTROLLER_NEW_SHELVE.getMoudleName(), "exception", IgnoreSomeException.filterSomeException(e), null));
return SearchApiResultUtils.errorSearchApiResult("searchNewestProductWithDiffBrand", paramMap, e);
}
}
private JSONArray getNewShelveResponseMap(final MultiBucketsAggregation aggregation) {
Iterator<? extends Bucket> itAgg = aggregation.getBuckets().iterator();
// 获取品牌聚合出来的商品
List<Map<String, Object>> productEsSourceList = new ArrayList<Map<String, Object>>();
while (itAgg.hasNext()) {
Bucket lt = itAgg.next();
if (lt.getAggregations().getAsMap().containsKey("product")) {
TopHits topHits = lt.getAggregations().get("product");
if (topHits != null) {
SearchHits hits = topHits.getHits();
for (SearchHit hit : hits.getHits()) {
productEsSourceList.add(hit.getSource());
}
}
}
}
List<Map<String, Object>> productListWithPricePlan = productIndexBaseService.getProductListWithPricePlan(productEsSourceList);
JSONArray results = new JSONArray();
for (Map<String, Object> productWithPricePlan : productListWithPricePlan) {
results.add(productWithPricePlan);
}
return results;
}
@Override
public SearchApiResult aggProductsByBrandIdInParam(Map<String, String> paramMap) {
... ...
... ... @@ -163,4 +163,28 @@ public class RobotQuestionServiceImpl extends BaseService implements IRobotQuest
productMap.put("updateTime", map.get("updateTime") == null ? "" : map.get("updateTime"));
return productMap;
}
@Override
public SearchApiResult queryRobotQuestionById(String id) {
//1、构造SearchParam
SearchParam searchParam = new SearchParam();
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
boolFilter.must(QueryBuilders.termQuery("id", id));
searchParam.setFiter(boolFilter);
searchParam.setSize(1);
//2、执行查询
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_ROBOTQUESTION, searchParam);
List<Map<String, Object>> resultList = searchResult.getResultList();
//3、构造返回结果
SearchApiResult searchApiResult = new SearchApiResult();
if(resultList==null || resultList.isEmpty()){
return searchApiResult.setMessage("id对应的数据不存在").setCode(400);
}
Map<String, Object> result = this.getRobotQuestionMap(resultList.get(0));
return searchApiResult.setData(result);
}
}
... ...
... ... @@ -15,6 +15,7 @@ import com.yoho.search.service.base.SearchCommonService;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.base.index.BrandIndexBaseService;
import com.yoho.search.service.base.index.ShopsIndexBaseService;
import com.yoho.search.service.helper.AggCommonHelper;
import com.yoho.search.service.helper.SearchCommonHelper;
import com.yoho.search.service.service.IShopListService;
import org.apache.commons.lang.StringUtils;
... ... @@ -151,20 +152,13 @@ public class ShopListServiceImpl implements IShopListService {
Bucket lt = itAgg.next();
if (lt.getAggregations().getAsMap().containsKey("product")) {
TopHits topHits = lt.getAggregations().get("product");
if (topHits != null) {
SearchHits hits = topHits.getHits();
for (SearchHit hit : hits.getHits()) {
Map<String, Object> source = hit.getSource();
float _score = hit.getScore();
source.put("_score", _score);
productSourceList.add(source);
}
}
productSourceList.addAll(AggCommonHelper.getTopHitResultsWithScore(topHits));
}
}
if (productSourceList == null || productSourceList.isEmpty()) {
return new ArrayList<Map<String, Object>>();
}
List<Integer> yohoShopIds = new ArrayList<Integer>();
List<Integer> globalBrandIds = new ArrayList<Integer>();
... ...
package com.yoho.search.service.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.yoho.error.event.SearchEvent;
import com.yoho.search.base.utils.CollectionUtils;
import com.yoho.search.base.utils.EventReportEnum;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.common.cache.CacheType;
import com.yoho.search.common.cache.SearchCacheFactory;
import com.yoho.search.common.cache.SearchCacheMatchLogger;
import com.yoho.search.common.cache.aop.SearchCacheAble;
import com.yoho.search.common.cache.model.SearchCache;
import com.yoho.search.common.utils.SearchApiResultUtils;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.core.es.utils.IgnoreSomeException;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.models.SearchSort;
import com.yoho.search.recall.scene.models.common.ParamQueryFilter;
import com.yoho.search.service.base.*;
import com.yoho.search.service.base.index.ProductIndexBaseService;
import com.yoho.search.service.base.index.WebProductIndexBaseService;
import com.yoho.search.service.helper.SearchParamHelper;
import com.yoho.search.service.helper.SearchServiceHelper;
import com.yoho.search.service.helper.SearchSortHelper;
import com.yoho.search.service.service.IWebNewShelveService;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.tophits.TopHits;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.*;
@Service
public class WebNewShelveServiceImpl implements IWebNewShelveService, ApplicationEventPublisherAware {
private static final Logger logger = LoggerFactory.getLogger(WebNewShelveServiceImpl.class);
@Autowired
private SearchSortHelper searchSortHelper;
@Autowired
private SearchParamHelper searchParamHelper;
@Autowired
private SearchServiceHelper searchServiceHelper;
@Autowired
private SearchCommonService searchCommonService;
@Autowired
private WebProductIndexBaseService webProductIndexBaseService;
@Autowired
private ProductListSortService productListSortService;
private ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
@Override
@SearchCacheAble(cacheName = "WEB_NEW_SHELVE",cacheInMinute = 30,cacheType = CacheType.SEARCH_REDIS,excludeParams={ "uid","udid"})
public SearchApiResult webNewShelveProductList(Map<String, String> paramMap) {
try {
logger.info("[func=aggProductsByBrandId][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());
// 1、参数校验
String sortField = searchSortHelper.getLegalOrder(paramMap);
if (StringUtils.isBlank(sortField)) {
sortField = "shelveTime:desc";
}
String[] sortParts = sortField.split(":");
String realSortField = sortParts[0];
String realSortType = sortParts[1];
// 2、构造查询条件
SearchParam searchParam = searchParamHelper.buildDefault(paramMap);
searchParam.setSize(0);
// 3、获取要取的品牌商品数量
int viewNum = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
if (viewNum > 100) {
viewNum = 100;
}
// 4、构造聚合条件
List<AbstractAggregationBuilder<?>> list = new ArrayList<AbstractAggregationBuilder<?>>();
boolean isAscOrder = SortOrder.ASC.toString().equalsIgnoreCase(realSortType);
// 4.1)构造父聚合:品牌聚合【同时按子聚合的sort字段排序】
TermsAggregationBuilder brandAggregationBuilder = AggregationBuilders.terms("brandAgg").field(ProductIndexEsField.brandId)
.order(Terms.Order.aggregation("sort", isAscOrder)).size(viewNum);
// 4.2)添加子聚合:sort值为sortFieldName的最大值或最小值,给父聚合排序用
if (isAscOrder) {
brandAggregationBuilder.subAggregation(AggregationBuilders.min("sort").field(realSortField));
} else {
brandAggregationBuilder.subAggregation(AggregationBuilders.max("sort").field(realSortField));
}
// 4.3)添加孙聚合:按sort取一个product
brandAggregationBuilder.subAggregation(AggregationBuilders.topHits("product")
.sort(SortBuilders.fieldSort(realSortField).order(isAscOrder ? SortOrder.ASC : SortOrder.DESC)).size(1));
list.add(brandAggregationBuilder);
searchParam.setAggregationBuilders(list);
// 5、构造返回结果
SearchApiResult searchApiResult = new SearchApiResult().setMessage("new-shelve list");
// 6、执行搜索,并构造返回结果
final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
if (searchResult == null || searchResult.getAggMaps() == null) {
return searchApiResult.setData("");
}
Map<String, Aggregation> aggMaps = searchResult.getAggMaps();
if (!aggMaps.containsKey("brandAgg")) {
return searchApiResult.setData("");
}
JSONArray productList = this.getNewShelveResponseMap(((MultiBucketsAggregation) aggMaps.get("brandAgg")));
return searchApiResult.setData(productList);
} catch (Exception e) {
publisher.publishEvent(new SearchEvent(EventReportEnum.SEARCHCONTROLLER_NEW_SHELVE.getEventName(), EventReportEnum.SEARCHCONTROLLER_NEW_SHELVE.getFunctionName(),
EventReportEnum.SEARCHCONTROLLER_NEW_SHELVE.getMoudleName(), "exception", IgnoreSomeException.filterSomeException(e), null));
return SearchApiResultUtils.errorSearchApiResult("searchNewestProductWithDiffBrand", paramMap, e);
}
}
private JSONArray getNewShelveResponseMap(final MultiBucketsAggregation aggregation) {
Iterator<? extends MultiBucketsAggregation.Bucket> itAgg = aggregation.getBuckets().iterator();
// 获取品牌聚合出来的商品
List<Map<String, Object>> productEsSourceList = new ArrayList<Map<String, Object>>();
while (itAgg.hasNext()) {
MultiBucketsAggregation.Bucket lt = itAgg.next();
if (lt.getAggregations().getAsMap().containsKey("product")) {
TopHits topHits = lt.getAggregations().get("product");
if (topHits != null) {
SearchHits hits = topHits.getHits();
for (SearchHit hit : hits.getHits()) {
productEsSourceList.add(hit.getSource());
}
}
}
}
List<Map<String, Object>> productListWithPricePlan = webProductIndexBaseService.getProductListWithPricePlan(productEsSourceList);
return this.transforToJSONArray(productListWithPricePlan);
}
private JSONArray transforToJSONArray(List<Map<String, Object>> productListWithPricePlan) {
JSONArray results = new JSONArray();
for (Map<String, Object> productWithPricePlan : productListWithPricePlan) {
results.add(productWithPricePlan);
}
return results;
}
@Override
@SearchCacheAble(cacheName = "WEB_BATCH_NEW_SHELVE",cacheInMinute = 30,cacheType = CacheType.SEARCH_REDIS,excludeParams={ "uid","udid"})
public SearchApiResult webNewShelveBatchProductList(Map<String, String> paramMap) {
try {
logger.info("[func=webNewShelvesProductList][param={}][begin={}]", paramMap.toString(), System.currentTimeMillis());
SearchApiResult searchApiResult = new SearchApiResult();
// 1、参数校验
String misortId = MapUtils.getString(paramMap, SearchRequestParams.PARAM_SEARCH_MIDDLESORT);
if (StringUtils.isBlank(misortId)) {
return searchApiResult.setCode(400).setMessage("请传misortId");
}
List<String> misortList = Arrays.asList(misortId.split(","));
//2、获取每个品类下的浏览数量
int viewNum = MapUtils.getIntValue(paramMap, SearchRequestParams.PARAM_SEARCH_VIEWNUM, 5);
if (viewNum > 10) {
viewNum = 10;
}
//3、解析排序
SearchSort searchSort = searchSortHelper.buildSearchSort(paramMap, "shelveTime:desc");
//4、构造SearchParams
List<SearchParam> searchParams = this.buildWebNewShelveSearchParams(paramMap, misortList, viewNum, searchSort);
//5、执行搜索
List<SearchResult> searchResultList = searchCommonService.doMutiSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParams);
//6、获取商品列表
JSONArray productList = this.getProductListFromSearchResult(searchResultList, viewNum);
return searchApiResult.setData(productList);
} catch (Exception e) {
return SearchApiResultUtils.errorSearchApiResult("webNewShelvesProductList", paramMap, e);
}
}
private List<SearchParam> buildWebNewShelveSearchParams(Map<String, String> paramMap, List<String> misortList, int viewNum, SearchSort searchSort) {
try {
//1、参数重组
Map<String, String> paramNew = new HashMap<>();
paramNew.putAll(paramMap);
paramNew.remove(SearchRequestParams.PARAM_SEARCH_MIDDLESORT);
//2、构造参数中的query和filter
QueryBuilder query = searchServiceHelper.constructQueryBuilder(paramNew);
BoolQueryBuilder filter = searchServiceHelper.constructFilterBuilder(paramNew, null);
//3、构造SearchParams
List<SearchParam> results = new ArrayList<>();
for (String misort : misortList) {
SearchParam searchParam = new SearchParam();
//1)构造query
searchParam.setQuery(query);
//2)构造filter
BoolQueryBuilder newFilter = QueryBuilders.boolQuery();
newFilter.must(filter);
newFilter.must(QueryBuilders.termQuery(ProductIndexEsField.middleSortId, misort));
searchParam.setFiter(newFilter);
//3)构造分页参数
searchParam.setOffset(0);
searchParam.setSize(30);
//4)构造排序
List<SortBuilder<?>> sortBuilders = new ArrayList<>();
sortBuilders.add(SortBuilders.fieldSort(searchSort.getSortField()).order(searchSort.getSortOrder()));
sortBuilders.add(SortBuilders.fieldSort(ProductIndexEsField.heatValue).order(SortOrder.DESC));
searchParam.setSortBuilders(sortBuilders);
//5)设置PC的返回字段
searchParam.setIncludeFields(webProductIndexBaseService.getWebProductIndexIncludeFields());
results.add(searchParam);
}
return results;
} catch (Exception e) {
return new ArrayList<>();
}
}
private JSONArray getProductListFromSearchResult(List<SearchResult> searchResultList, int viewNum) {
List<Map<String, Object>> productEsSourceList = new ArrayList<>();
for (SearchResult searchResult : searchResultList) {
List<Map<String, Object>> esProductList = searchResult.getResultList();
esProductList = productListSortService.sortProductList(esProductList, new ProductListSortKey<Map<String, Object>>() {
@Override
public String getSortKey(Map<String, Object> product) {
return MapUtils.getString(product, ProductIndexEsField.brandId, "0");
}
@Override
public int getMaxCount() {
return 1;
}
});
esProductList = CollectionUtils.safeSubList(esProductList, 0, viewNum);
productEsSourceList.addAll(esProductList);
}
List<Map<String, Object>> productListWithPricePlan = webProductIndexBaseService.getProductListWithPricePlan(productEsSourceList);
return this.transforToJSONArray(productListWithPricePlan);
}
}
... ...