|
|
package com.yoho.search.service.scene.ufo;
|
|
|
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.yoho.search.aop.cache.SearchCacheAble;
|
|
|
import com.yoho.search.base.constants.ISearchConstants;
|
|
|
import com.yoho.search.base.constants.UfoProductIndexEsField;
|
|
|
import com.yoho.search.base.constants.UfoStoragePriceIndexEsField;
|
|
|
import com.yoho.search.base.utils.SearchConvertUtils;
|
|
|
import com.yoho.search.cache.CacheInMinute;
|
|
|
import com.yoho.search.common.SearchCommonService;
|
|
|
import com.yoho.search.common.UfoSearchRequestParams;
|
|
|
import com.yoho.search.common.utils.SearchApiResultUtils;
|
|
|
import com.yoho.search.core.es.agg.IAggregation;
|
|
|
import com.yoho.search.core.es.model.SearchParam;
|
|
|
import com.yoho.search.core.es.model.SearchResult;
|
|
|
import com.yoho.search.models.SearchApiResult;
|
|
|
import com.yoho.search.service.aggregations.impls.AggregationFactory;
|
|
|
import com.yoho.search.service.helper.UfoSearchQueryHelper;
|
|
|
import com.yoho.search.service.index.ufo.UfoProductIndexBaseService;
|
|
|
import com.yoho.search.service.index.ufo.UfoStoragePriceIndexBaseService;
|
...
|
...
|
@@ -20,6 +24,9 @@ import org.apache.commons.collections.MapUtils; |
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.elasticsearch.index.query.BoolQueryBuilder;
|
|
|
import org.elasticsearch.index.query.QueryBuilders;
|
|
|
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
|
|
|
import org.elasticsearch.search.aggregations.Aggregation;
|
|
|
import org.elasticsearch.search.sort.SortBuilder;
|
|
|
import org.elasticsearch.search.sort.SortBuilders;
|
|
|
import org.elasticsearch.search.sort.SortOrder;
|
|
|
import org.slf4j.Logger;
|
...
|
...
|
@@ -27,6 +34,7 @@ import org.slf4j.LoggerFactory; |
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import javax.annotation.PostConstruct;
|
|
|
import java.util.*;
|
|
|
|
|
|
/**
|
...
|
...
|
@@ -45,6 +53,76 @@ public class UfoSecondhandSkupService { |
|
|
private UfoProductIndexBaseService ufoProductIndexBaseService;
|
|
|
@Autowired
|
|
|
private UfoSearchQueryHelper ufoSearchQueryHelper;
|
|
|
@Autowired
|
|
|
private AggregationFactory aggregationFactory;
|
|
|
|
|
|
private Set<String> orderValues = new HashSet<>();
|
|
|
|
|
|
@PostConstruct
|
|
|
private void init() {
|
|
|
//默认
|
|
|
orderValues.add("id:desc");
|
|
|
//价格
|
|
|
orderValues.add("price:asc");
|
|
|
orderValues.add("price:desc");
|
|
|
}
|
|
|
|
|
|
// 构造排序参数
|
|
|
private List<SortBuilder<?>> buildSortBuilders(Map<String, String> paramMap) {
|
|
|
String order = paramMap.get("order");
|
|
|
if (StringUtils.isBlank(order) || !orderValues.contains(order)) {
|
|
|
return Arrays.asList(SortBuilders.fieldSort("id").order(SortOrder.DESC));
|
|
|
}
|
|
|
String[] sortParts = order.split(ISearchConstants.SPLIT_CHAR_COLON);
|
|
|
String fieldName = sortParts[0];
|
|
|
SortOrder sortOrder = SortOrder.ASC.toString().equals(sortParts[1]) ? SortOrder.ASC : SortOrder.DESC;
|
|
|
return Arrays.asList(SortBuilders.fieldSort(fieldName).order(sortOrder), SortBuilders.fieldSort("id").order(SortOrder.DESC));
|
|
|
}
|
|
|
|
|
|
// 构造过滤参数
|
|
|
private BoolQueryBuilder builderFilter(Map<String, String> paramMap) {
|
|
|
BoolQueryBuilder filter = QueryBuilders.boolQuery();
|
|
|
// 硬过滤
|
|
|
filter.must(QueryBuilders.termQuery(UfoStoragePriceIndexEsField.isHide, 0));
|
|
|
filter.must(QueryBuilders.termQuery(UfoStoragePriceIndexEsField.status, 1));
|
|
|
|
|
|
// 防止翻页重复,过滤最大id
|
|
|
int maxStoragePriceId = MapUtils.getIntValue(paramMap, UfoSearchRequestParams.UFO_PARAM_MAXSTORAGEPRICE_ID, Integer.MAX_VALUE);
|
|
|
filter.must(QueryBuilders.rangeQuery(UfoStoragePriceIndexEsField.id).lte(maxStoragePriceId));
|
|
|
|
|
|
// 支持过滤类型,默认5,6
|
|
|
List<Integer> preSaleFlags = SearchConvertUtils.stringToIntList(MapUtils.getString(paramMap, UfoSearchRequestParams.UFO_PARAM_PRE_SALE_FLAG), ",");
|
|
|
if (CollectionUtils.isNotEmpty(preSaleFlags)) {
|
|
|
filter.must(QueryBuilders.termsQuery(UfoStoragePriceIndexEsField.preSaleFlag, preSaleFlags));
|
|
|
} else {
|
|
|
filter.must(QueryBuilders.termsQuery(UfoStoragePriceIndexEsField.preSaleFlag, Arrays.asList(5, 6)));
|
|
|
}
|
|
|
// 支持过滤showChannel
|
|
|
ufoSearchQueryHelper.addMustIntTermsQuery(filter, paramMap, UfoSearchRequestParams.UFO_PARAM_SHOW_CHANNEL, UfoStoragePriceIndexEsField.showChannel);
|
|
|
// 支持过滤性别
|
|
|
ufoSearchQueryHelper.addMustIntTermsQuery(filter, paramMap, UfoSearchRequestParams.UFO_PARAM_GENDER, UfoStoragePriceIndexEsField.gender);
|
|
|
// 支持过滤尺码
|
|
|
ufoSearchQueryHelper.addMustIntTermsQuery(filter, paramMap, UfoSearchRequestParams.UFO_PARAM_SIZE, UfoStoragePriceIndexEsField.sizeId);
|
|
|
// 支持过滤品牌
|
|
|
ufoSearchQueryHelper.addMustIntTermsQuery(filter, paramMap, UfoSearchRequestParams.UFO_PARAM_BRAND, UfoStoragePriceIndexEsField.brandId);
|
|
|
// 支持商品池参数
|
|
|
ufoSearchQueryHelper.addMustIntTermsQuery(filter, paramMap, UfoSearchRequestParams.UFO_PARAM_POOL, UfoStoragePriceIndexEsField.poolIds);
|
|
|
// 支持过滤价格
|
|
|
ufoSearchQueryHelper.addMustDoubleRangeQuery(filter, paramMap, UfoSearchRequestParams.UFO_PARAM_PRICE, UfoStoragePriceIndexEsField.price);
|
|
|
return filter;
|
|
|
}
|
|
|
|
|
|
private SearchParam buildSearchParam(Map<String, String> paramMap, int page, int pageSize) {
|
|
|
SearchParam searchParam = new SearchParam();
|
|
|
// 1、构建Filter
|
|
|
searchParam.setFiter(this.builderFilter(paramMap));
|
|
|
// 2、设置排序字段
|
|
|
searchParam.setSortBuilders(this.buildSortBuilders(paramMap));
|
|
|
// 3、构建分页参数
|
|
|
searchParam.setSize(pageSize);
|
|
|
searchParam.setOffset((page - 1) * pageSize);
|
|
|
return searchParam;
|
|
|
}
|
|
|
|
|
|
@SearchCacheAble(cacheName = "SECONDEHAND_SKUP_LIST", cacheInMinute = CacheInMinute.Minute_UFO)
|
|
|
public SearchApiResult secondHandSkupList(Map<String, String> paramMap) {
|
...
|
...
|
@@ -57,37 +135,32 @@ public class UfoSecondhandSkupService { |
|
|
return new SearchApiResult().setCode(400).setMessage("分页参数不合法");
|
|
|
}
|
|
|
// 2、构造SearchParam
|
|
|
SearchParam searchParam = new SearchParam();
|
|
|
BoolQueryBuilder boolFilter = this.builderFilter(paramMap);
|
|
|
searchParam.setFiter(boolFilter);
|
|
|
searchParam.setQuery(QueryBuilders.matchAllQuery());
|
|
|
// 3、构建分页参数
|
|
|
searchParam.setSize(pageSize);
|
|
|
searchParam.setOffset((page - 1) * pageSize);
|
|
|
// 4、设置排序字段
|
|
|
searchParam.setSortBuilders(Arrays.asList(SortBuilders.fieldSort("id").order(SortOrder.DESC)));
|
|
|
// 5、执行搜索
|
|
|
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_UFO_STORAGE_PRICE, searchParam);
|
|
|
// 6、构造搜索结果
|
|
|
SearchParam searchParams = this.buildSearchParam(paramMap, page, pageSize);
|
|
|
|
|
|
// 3、执行搜索
|
|
|
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_UFO_STORAGE_PRICE, searchParams);
|
|
|
|
|
|
// 4、构造搜索结果
|
|
|
List<Map<String, Object>> skupResultList = new ArrayList<>();
|
|
|
List<Integer> ufoProductIds = new ArrayList<>();
|
|
|
List<Integer> ufoStorageIds = new ArrayList<>();
|
|
|
for (Map<String, Object> skupEsSource : searchResult.getResultList()) {
|
|
|
skupResultList.add(ufoStoragePriceIndexBaseService.buildStoragePriceMap(skupEsSource));
|
|
|
ufoProductIds.add(MapUtils.getIntValue(skupEsSource, "productId", 0));
|
|
|
ufoStorageIds.add(MapUtils.getIntValue(skupEsSource, "storageId", 0));
|
|
|
ufoProductIds.add(MapUtils.getIntValue(skupEsSource, UfoStoragePriceIndexEsField.productId, 0));
|
|
|
ufoStorageIds.add(MapUtils.getIntValue(skupEsSource, UfoStoragePriceIndexEsField.storageId, 0));
|
|
|
}
|
|
|
// 7、根据ufoStorageIds查询最低价信息
|
|
|
|
|
|
// 5、根据ufoStorageIds查询最低价信息
|
|
|
Map<Integer, Double> storageAvailableNowPriceMap = this.queryAvailableNowPriceByStorageIds(ufoStorageIds);
|
|
|
|
|
|
// 8、根据productIds查询商品信息
|
|
|
// 6、根据productIds查询商品信息
|
|
|
Map<Integer, Map<String, Object>> ufoProductMap = ufoProductIndexBaseService.queryUfoProductMapByProductIds(ufoProductIds);
|
|
|
|
|
|
// 9、处理结果
|
|
|
for(Map<String, Object> skupResult:skupResultList){
|
|
|
for (Map<String, Object> skupResult : skupResultList) {
|
|
|
//1) 价格处理[现货最低价-skupPrice]
|
|
|
double skupPrice = MapUtils.getDoubleValue(skupResult, "skup_price", 0);
|
|
|
int storageId = MapUtils.getIntValue(skupResult,"storage_id",0);
|
|
|
int storageId = MapUtils.getIntValue(skupResult, "storage_id", 0);
|
|
|
double available_now_price = MapUtils.getDoubleValue(storageAvailableNowPriceMap, storageId, 0);
|
|
|
skupResult.put("available_now_price", available_now_price);
|
|
|
if (skupPrice > 0 && available_now_price > 0 && skupPrice < available_now_price) {
|
...
|
...
|
@@ -123,24 +196,6 @@ public class UfoSecondhandSkupService { |
|
|
}
|
|
|
}
|
|
|
|
|
|
private BoolQueryBuilder builderFilter(Map<String, String> paramMap) {
|
|
|
BoolQueryBuilder filter = QueryBuilders.boolQuery();
|
|
|
// 硬过滤
|
|
|
int maxStoragePriceId = MapUtils.getIntValue(paramMap, UfoSearchRequestParams.UFO_PARAM_MAXSTORAGEPRICE_ID, Integer.MAX_VALUE);
|
|
|
filter.must(QueryBuilders.rangeQuery("id").lte(maxStoragePriceId));
|
|
|
filter.must(QueryBuilders.termQuery("isHide", 0));
|
|
|
filter.must(QueryBuilders.termQuery("status", 1));
|
|
|
// 过滤preSaleFlag,默认5,6
|
|
|
List<Integer> preSaleFlags = SearchConvertUtils.stringToIntList(MapUtils.getString(paramMap, UfoSearchRequestParams.UFO_PARAM_PRE_SALE_FLAG), ",");
|
|
|
if (CollectionUtils.isNotEmpty(preSaleFlags)) {
|
|
|
filter.must(QueryBuilders.termsQuery("preSaleFlag", preSaleFlags));
|
|
|
} else {
|
|
|
filter.must(QueryBuilders.termsQuery("preSaleFlag", Arrays.asList(5, 6)));
|
|
|
}
|
|
|
// 支持过滤showChannel
|
|
|
ufoSearchQueryHelper.addMustIntTermsQuery(filter, paramMap, UfoSearchRequestParams.UFO_PARAM_SHOW_CHANNEL, UfoProductIndexEsField.showChannel);
|
|
|
return filter;
|
|
|
}
|
|
|
|
|
|
//查询每个storage对应的现货最低价
|
|
|
private Map<Integer, Double> queryAvailableNowPriceByStorageIds(final Collection<?> ufoStorageIds) {
|
...
|
...
|
@@ -162,4 +217,91 @@ public class UfoSecondhandSkupService { |
|
|
}
|
|
|
}
|
|
|
|
|
|
//二手列表筛选项
|
|
|
@SearchCacheAble(cacheName = "SECONDEHAND_AGGREGATION", cacheInMinute = CacheInMinute.Minute_UFO)
|
|
|
public SearchApiResult secondHandAggregation(Map<String, String> paramMap) {
|
|
|
SearchParam searchParam = new SearchParam();
|
|
|
// 1、构建Filter
|
|
|
searchParam.setFiter(this.builderFilter(paramMap));
|
|
|
searchParam.setSize(0);
|
|
|
//2、构建聚合参数
|
|
|
searchParam.setAggregationBuilders(this.buildAggs(paramMap));
|
|
|
// 3、查询
|
|
|
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_UFO_STORAGE_PRICE, searchParam);
|
|
|
// 4、构造结果
|
|
|
Map<String, Aggregation> aggMaps = searchResult.getAggMaps();
|
|
|
if (aggMaps == null) {
|
|
|
return null;
|
|
|
}
|
|
|
// 构造返回结果
|
|
|
JSONObject dataMap = new JSONObject();
|
|
|
dataMap.put("filter", this.getAggResultMap(paramMap, aggMaps));
|
|
|
return new SearchApiResult().setData(dataMap);
|
|
|
}
|
|
|
|
|
|
private List<AbstractAggregationBuilder<?>> buildAggs(Map<String, String> paramMap) {
|
|
|
List<AbstractAggregationBuilder<?>> list = new ArrayList<AbstractAggregationBuilder<?>>();
|
|
|
//品牌
|
|
|
list.add(aggregationFactory.getUfoBrandAggregation(paramMap).getBuilder());
|
|
|
//性别
|
|
|
list.add(aggregationFactory.getUfoGenderAggregation().getBuilder());
|
|
|
//尺码
|
|
|
list.add(aggregationFactory.getUfoSizeAggregation(UfoStoragePriceIndexEsField.sizeId).getBuilder());
|
|
|
//二手类型
|
|
|
list.add(aggregationFactory.getUfoPreSaleFlagAggregation().getBuilder());
|
|
|
//价格
|
|
|
list.add(aggregationFactory.getUfoPriceAggregation().getBuilder());
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
private Map<String, Object> getAggResultMap(Map<String, String> paramMap, Map<String, Aggregation> aggMaps) {
|
|
|
Map<String, Object> filter = new HashMap<String, Object>();
|
|
|
|
|
|
// 品牌层面的聚合结果
|
|
|
IAggregation brandAggregation = aggregationFactory.getUfoBrandAggregation(paramMap);
|
|
|
Object brandResponse = brandAggregation.getAggregationResponseMap(aggMaps);
|
|
|
if (brandResponse != null) {
|
|
|
filter.put("brand", brandResponse);
|
|
|
} else {
|
|
|
filter.put("brand", new JSONArray());
|
|
|
}
|
|
|
|
|
|
// 性别的聚合结果
|
|
|
IAggregation genderAggregation = aggregationFactory.getUfoGenderAggregation();
|
|
|
Object genderResponse = genderAggregation.getAggregationResponseMap(aggMaps);
|
|
|
if (genderResponse != null) {
|
|
|
filter.put("gender", genderResponse);
|
|
|
} else {
|
|
|
filter.put("gender", new JSONArray());
|
|
|
}
|
|
|
|
|
|
// 尺码
|
|
|
IAggregation sizeAggregation = aggregationFactory.getUfoSizeAggregation(UfoProductIndexEsField.sizeIds);
|
|
|
Object sizeResponse = sizeAggregation.getAggregationResponseMap(aggMaps);
|
|
|
if (sizeResponse != null) {
|
|
|
filter.put("size", sizeResponse);
|
|
|
} else {
|
|
|
filter.put("size", new JSONArray());
|
|
|
}
|
|
|
|
|
|
//二手类型
|
|
|
IAggregation preSaleFlagAggregation = aggregationFactory.getUfoPreSaleFlagAggregation();
|
|
|
Object preSaleFlagResponse = preSaleFlagAggregation.getAggregationResponseMap(aggMaps);
|
|
|
if (preSaleFlagResponse != null) {
|
|
|
filter.put("preSaleFlag", preSaleFlagResponse);
|
|
|
} else {
|
|
|
filter.put("preSaleFlag", new JSONArray());
|
|
|
}
|
|
|
|
|
|
//价格
|
|
|
IAggregation priceAggregation = aggregationFactory.getUfoPriceAggregation();
|
|
|
Object priceResponse = priceAggregation.getAggregationResponseMap(aggMaps);
|
|
|
if (priceResponse != null) {
|
|
|
filter.put("price", priceResponse);
|
|
|
} else {
|
|
|
filter.put("price", new JSONArray());
|
|
|
}
|
|
|
return filter;
|
|
|
}
|
|
|
|
|
|
} |
...
|
...
|
|