|
|
package com.yoho.search.service.scene.general;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
|
|
|
import com.yoho.error.event.SearchEvent;
|
|
|
import com.yoho.search.base.utils.ConvertUtils;
|
|
|
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.cache.beans.AbstractCacheAbleService;
|
|
|
import com.yoho.search.cache.model.SearchCache;
|
|
|
import com.yoho.search.common.utils.HttpServletRequestUtils;
|
|
|
import com.yoho.search.cache.CacheTimeConstants;
|
|
|
import com.yoho.search.cache.beans.AbstractCacheComponent;
|
|
|
import com.yoho.search.common.SearchCommonService;
|
|
|
import com.yoho.search.common.SearchRequestParams;
|
|
|
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.core.es.utils.IgnoreSomeException;
|
|
|
import com.yoho.search.models.SearchApiResult;
|
|
|
import com.yoho.search.service.aggregations.impls.AggregationFactory;
|
|
|
import com.yoho.search.common.SearchCommonService;
|
|
|
import com.yoho.search.common.SearchRequestParams;
|
|
|
import com.yoho.search.service.helper.SearchCommonHelper;
|
|
|
import com.yoho.search.service.helper.SearchParamHelper;
|
|
|
import com.yoho.search.service.recall.models.common.ParamQueryFilter;
|
|
|
import org.apache.commons.collections.MapUtils;
|
|
|
import org.elasticsearch.index.query.BoolQueryBuilder;
|
|
|
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.yoho.search.models.SearchApiResult;
|
|
|
import org.elasticsearch.index.query.QueryBuilders;
|
|
|
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
|
|
|
import org.slf4j.Logger;
|
...
|
...
|
@@ -35,166 +33,140 @@ import org.springframework.context.ApplicationEventPublisher; |
|
|
import org.springframework.context.ApplicationEventPublisherAware;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
|
|
|
@Service
|
|
|
public class SortGroupService extends AbstractCacheAbleService implements ApplicationEventPublisherAware {
|
|
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(SortGroupService.class);
|
|
|
|
|
|
private static Logger CACHE_MATCH_REQUEST = LoggerFactory.getLogger("CACHE_MATCH_REQUEST");
|
|
|
|
|
|
@Autowired
|
|
|
private SearchCommonHelper searchCommonHelper;
|
|
|
@Autowired
|
|
|
private SearchCommonService searchCommonService;
|
|
|
@Autowired
|
|
|
private AggregationFactory aggregationFactory;
|
|
|
@Autowired
|
|
|
private SearchParamHelper searchParamHelper;
|
|
|
|
|
|
@Override
|
|
|
public SearchCache getSearchCache() {
|
|
|
return searchCacheFactory.getAggregationSearchCache();
|
|
|
}
|
|
|
|
|
|
ApplicationEventPublisher publisher;
|
|
|
|
|
|
@Override
|
|
|
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
|
|
this.publisher = applicationEventPublisher;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 对分类进行分组查询
|
|
|
*
|
|
|
* @needAllSort=1时过滤条件status和gender生效
|
|
|
* @否则其他参数也会生效
|
|
|
* @param paramMap
|
|
|
* @return
|
|
|
* @throws Exception
|
|
|
*/
|
|
|
public SearchApiResult sortGroup(Map<String, String> paramMap) {
|
|
|
try {
|
|
|
long begin = System.currentTimeMillis();
|
|
|
logger.info("[model=SearchSortGroupService][func=sortGroup][param={}][begin={}]", paramMap.toString(), begin);
|
|
|
// 如果包含参数needAllSort=1
|
|
|
SearchParam searchParam = new SearchParam();
|
|
|
if (!paramMap.containsKey("needAllSort") || !"1".equals(paramMap.get("needAllSort"))) {
|
|
|
searchParam = searchParamHelper.buildDefault(paramMap);
|
|
|
} else {
|
|
|
// needAllSort=1时过滤条件只有status和gender生效
|
|
|
searchParam.setQuery(QueryBuilders.matchAllQuery());
|
|
|
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
|
|
|
if (paramMap.containsKey(SearchRequestParams.PARAM_SEARCH_STATUS)) {
|
|
|
boolFilter.must(QueryBuilders.termQuery(SearchRequestParams.PARAM_SEARCH_STATUS, paramMap.get(SearchRequestParams.PARAM_SEARCH_STATUS)));
|
|
|
}
|
|
|
// 性别
|
|
|
if (paramMap.containsKey(SearchRequestParams.PARAM_SEARCH_GENDER)) {
|
|
|
String[] genders = paramMap.get(SearchRequestParams.PARAM_SEARCH_GENDER).split(",");
|
|
|
boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.gender, genders));
|
|
|
}
|
|
|
// 如果contain_global!=Y,则过滤掉全球购的商品[全球购商品融合需求]
|
|
|
if (!searchCommonHelper.containGlobal(paramMap)) {
|
|
|
boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isGlobal, "Y"));
|
|
|
}
|
|
|
if (boolFilter.hasClauses()) {
|
|
|
searchParam.setFiter(boolFilter);
|
|
|
}
|
|
|
}
|
|
|
// 构造聚合条件
|
|
|
List<AbstractAggregationBuilder<?>> sortGroupBuilders = new ArrayList<AbstractAggregationBuilder<?>>();
|
|
|
IAggregation sortGroupAggregation = aggregationFactory.getSortGroupAggregation(paramMap);
|
|
|
sortGroupBuilders.add(sortGroupAggregation.getBuilder());
|
|
|
searchParam.setAggregationBuilders(sortGroupBuilders);
|
|
|
|
|
|
// 设置查询结果
|
|
|
searchParam.setOffset(1);// just for cache
|
|
|
searchParam.setSize(0);
|
|
|
|
|
|
// 构造返回结果
|
|
|
SearchApiResult searchApiResult = new SearchApiResult();
|
|
|
searchApiResult.setCode(200);
|
|
|
searchApiResult.setMessage("sort List.");
|
|
|
|
|
|
// 先从缓存中获取,如果能取到,则直接返回
|
|
|
JSONObject cacheObject = searchCacheService.getJSONObjectFromCache(this.searchCache, ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
|
|
|
if (cacheObject != null) {
|
|
|
searchApiResult.setData(cacheObject);
|
|
|
CACHE_MATCH_REQUEST.info("match cache , url is :/sortgroup.json?" + HttpServletRequestUtils.genParamString(paramMap));
|
|
|
return searchApiResult;
|
|
|
}
|
|
|
|
|
|
// 进行检索
|
|
|
final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
|
|
|
SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
|
|
|
if (searchResult == null || searchResult.getAggMaps() == null || !searchResult.getAggMaps().containsKey("maxAgg")) {
|
|
|
searchApiResult.setData("");
|
|
|
return searchApiResult;
|
|
|
}
|
|
|
|
|
|
// 获取品类聚合结果
|
|
|
JSONArray sortGroups = (JSONArray) sortGroupAggregation.getAggregationResponseMap(searchResult.getAggMaps());
|
|
|
if (sortGroups == null) {
|
|
|
searchApiResult.setData("");
|
|
|
return searchApiResult;
|
|
|
}
|
|
|
// 构造data并加入缓存
|
|
|
JSONObject sortResult = new JSONObject();
|
|
|
sortResult.put("sort", sortGroups);
|
|
|
searchCacheService.addJSONObjectToCache(this.searchCache, indexName, searchParam, sortResult);
|
|
|
|
|
|
return searchApiResult.setData(sortResult);
|
|
|
} catch (Exception e) {
|
|
|
publisher.publishEvent(new SearchEvent(EventReportEnum.SEARCHCONTROLLER_SORTGROUP.getEventName(), EventReportEnum.SEARCHCONTROLLER_SORTGROUP.getFunctionName(),
|
|
|
EventReportEnum.SEARCHCONTROLLER_SORTGROUP.getMoudleName(), "exception", IgnoreSomeException.filterSomeException(e), null));
|
|
|
return SearchApiResultUtils.errorSearchApiResult(logger, paramMap, e);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public JSONArray sortGroup(Map<String, String> paramMap, BoolQueryBuilder mustFilter) {
|
|
|
try {
|
|
|
long begin = System.currentTimeMillis();
|
|
|
logger.info("[model=SearchSortGroupService][func=sortGroup][param={}][begin={}]", paramMap.toString(), begin);
|
|
|
SearchParam searchParam = searchParamHelper.buildWithMustFilter(paramMap, mustFilter);
|
|
|
|
|
|
// 构造聚合条件
|
|
|
List<AbstractAggregationBuilder<?>> sortGroupBuilders = new ArrayList<AbstractAggregationBuilder<?>>();
|
|
|
IAggregation sortGroupAggregation = aggregationFactory.getSortGroupAggregation(paramMap);
|
|
|
sortGroupBuilders.add(sortGroupAggregation.getBuilder());
|
|
|
searchParam.setAggregationBuilders(sortGroupBuilders);
|
|
|
|
|
|
// 设置返回结果为0
|
|
|
searchParam.setSize(0);
|
|
|
|
|
|
// 先从缓存中获取,如果能取到,则直接返回
|
|
|
JSONObject cacheObject = searchCacheService.getJSONObjectFromCache(this.searchCache, ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
|
|
|
if (cacheObject != null) {
|
|
|
return cacheObject.getJSONArray("sort");
|
|
|
}
|
|
|
|
|
|
// 进行检索
|
|
|
final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
|
|
|
SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
|
|
|
if (searchResult == null || searchResult.getAggMaps() == null || !searchResult.getAggMaps().containsKey("maxAgg")) {
|
|
|
return new JSONArray();
|
|
|
}
|
|
|
|
|
|
// 获取品类聚合结果
|
|
|
JSONArray sortGroups = (JSONArray) sortGroupAggregation.getAggregationResponseMap(searchResult.getAggMaps());
|
|
|
if (sortGroups == null) {
|
|
|
return new JSONArray();
|
|
|
}
|
|
|
|
|
|
JSONObject sortResult = new JSONObject();
|
|
|
sortResult.put("sort", sortGroups);
|
|
|
searchCacheService.addJSONObjectToCache(this.searchCache, indexName, searchParam, sortResult);
|
|
|
return sortGroups;
|
|
|
} catch (Exception e) {
|
|
|
publisher.publishEvent(new SearchEvent(EventReportEnum.SEARCHCONTROLLER_SORTGROUP.getEventName(), EventReportEnum.SEARCHCONTROLLER_SORTGROUP.getFunctionName(),
|
|
|
EventReportEnum.SEARCHCONTROLLER_SORTGROUP.getMoudleName(), "exception", IgnoreSomeException.filterSomeException(e), null));
|
|
|
return new JSONArray();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class SortGroupService extends AbstractCacheComponent<JSONArray> implements ApplicationEventPublisherAware {
|
|
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(SortGroupService.class);
|
|
|
|
|
|
private ApplicationEventPublisher publisher;
|
|
|
|
|
|
@Override
|
|
|
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
|
|
this.publisher = applicationEventPublisher;
|
|
|
}
|
|
|
|
|
|
@Autowired
|
|
|
private SearchCommonHelper searchCommonHelper;
|
|
|
@Autowired
|
|
|
private SearchCommonService searchCommonService;
|
|
|
@Autowired
|
|
|
private AggregationFactory aggregationFactory;
|
|
|
@Autowired
|
|
|
private SearchParamHelper searchParamHelper;
|
|
|
|
|
|
/**
|
|
|
* 对分类进行分组查询
|
|
|
*
|
|
|
* @param paramMap
|
|
|
* @return
|
|
|
* @throws Exception
|
|
|
* @needAllSort=1时过滤条件status和gender生效
|
|
|
* @否则其他参数也会生效
|
|
|
*/
|
|
|
public SearchApiResult sortGroup(Map<String, String> paramMap) {
|
|
|
try {
|
|
|
//1、构建paramQueryFilter
|
|
|
ParamQueryFilter paramQueryFilter;
|
|
|
if ("1".equals(MapUtils.getString(paramMap, "needAllSort"))) {
|
|
|
BoolQueryBuilder boolFilter = this.buildFilterForNeedAllSort(paramMap);
|
|
|
paramQueryFilter = new ParamQueryFilter(QueryBuilders.matchAllQuery(), boolFilter);
|
|
|
} else {
|
|
|
paramQueryFilter = searchParamHelper.buildParamQueryFilter(paramMap);
|
|
|
}
|
|
|
//2、调父类执行查询
|
|
|
JSONArray sortGroupResult = super.queryWithCache(paramQueryFilter, paramMap);
|
|
|
// 3、构造返回结果
|
|
|
SearchApiResult searchApiResult = new SearchApiResult();
|
|
|
searchApiResult.setCode(200);
|
|
|
searchApiResult.setMessage("sort List.");
|
|
|
JSONObject sortResult = new JSONObject();
|
|
|
sortResult.put("sort", sortGroupResult);
|
|
|
return searchApiResult.setData(sortResult);
|
|
|
} catch (Exception e) {
|
|
|
publisher.publishEvent(new SearchEvent(EventReportEnum.SEARCHCONTROLLER_SORTGROUP.getEventName(), EventReportEnum.SEARCHCONTROLLER_SORTGROUP.getFunctionName(),
|
|
|
EventReportEnum.SEARCHCONTROLLER_SORTGROUP.getMoudleName(), "exception", IgnoreSomeException.filterSomeException(e), null));
|
|
|
return SearchApiResultUtils.errorSearchApiResult(logger, paramMap, e);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 当needAllSort=1时,只有status和gender参数生效
|
|
|
*
|
|
|
* @param paramMap
|
|
|
* @return
|
|
|
*/
|
|
|
private BoolQueryBuilder buildFilterForNeedAllSort(Map<String, String> paramMap) {
|
|
|
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
|
|
|
if (paramMap.containsKey(SearchRequestParams.PARAM_SEARCH_STATUS)) {
|
|
|
boolFilter.must(QueryBuilders.termQuery(SearchRequestParams.PARAM_SEARCH_STATUS, paramMap.get(SearchRequestParams.PARAM_SEARCH_STATUS)));
|
|
|
}
|
|
|
// 性别
|
|
|
if (paramMap.containsKey(SearchRequestParams.PARAM_SEARCH_GENDER)) {
|
|
|
List<String> genders = ConvertUtils.stringToStringList(paramMap.get(SearchRequestParams.PARAM_SEARCH_GENDER), ",");
|
|
|
boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.gender, genders));
|
|
|
}
|
|
|
// 如果contain_global!=Y,则过滤掉全球购的商品[全球购商品融合需求]
|
|
|
if (!searchCommonHelper.containGlobal(paramMap)) {
|
|
|
boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isGlobal, "Y"));
|
|
|
}
|
|
|
return boolFilter;
|
|
|
}
|
|
|
|
|
|
public JSONArray sortGroup(Map<String, String> paramMap, BoolQueryBuilder mustFilter) {
|
|
|
try {
|
|
|
ParamQueryFilter paramQueryFilter = searchParamHelper.buildParamQueryFilter(paramMap, mustFilter);
|
|
|
return super.queryWithCache(paramQueryFilter, paramMap);
|
|
|
} catch (Exception e) {
|
|
|
publisher.publishEvent(new SearchEvent(EventReportEnum.SEARCHCONTROLLER_SORTGROUP.getEventName(), EventReportEnum.SEARCHCONTROLLER_SORTGROUP.getFunctionName(),
|
|
|
EventReportEnum.SEARCHCONTROLLER_SORTGROUP.getMoudleName(), "exception", IgnoreSomeException.filterSomeException(e), null));
|
|
|
return new JSONArray();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
protected JSONArray doRealQuery(ParamQueryFilter paramQueryFilter, Map<String, String> paramMap) throws Exception {
|
|
|
//1、构造SearchParam
|
|
|
SearchParam searchParam = searchParamHelper.buildSearchParam(paramQueryFilter);
|
|
|
|
|
|
// 2、构造聚合条件
|
|
|
List<AbstractAggregationBuilder<?>> sortGroupBuilders = new ArrayList<AbstractAggregationBuilder<?>>();
|
|
|
IAggregation sortGroupAggregation = aggregationFactory.getSortGroupAggregation(paramMap);
|
|
|
sortGroupBuilders.add(sortGroupAggregation.getBuilder());
|
|
|
searchParam.setAggregationBuilders(sortGroupBuilders);
|
|
|
|
|
|
///3、设置返回结果为0
|
|
|
searchParam.setSize(0);
|
|
|
|
|
|
// 4、进行检索
|
|
|
final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
|
|
|
SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
|
|
|
if (searchResult == null || searchResult.getAggMaps() == null || !searchResult.getAggMaps().containsKey("maxAgg")) {
|
|
|
return new JSONArray();
|
|
|
}
|
|
|
|
|
|
// 5、获取品类聚合结果
|
|
|
JSONArray sortGroups = (JSONArray) sortGroupAggregation.getAggregationResponseMap(searchResult.getAggMaps());
|
|
|
return sortGroups == null ? new JSONArray() : sortGroups;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
protected int cacheTimeInMinute() {
|
|
|
return CacheTimeConstants.CACHE_15_MINUTE;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
protected String cacheSceneKey() {
|
|
|
return "SORT_GROUP";
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
protected RedisKeyBuilder genRedisKeyBuilder(ParamQueryFilter paramQueryFilter, Map<String,String> paramMap){
|
|
|
RedisKeyBuilder redisKeyBuilder = super.genRedisKeyBuilder(paramQueryFilter,paramMap);
|
|
|
redisKeyBuilder.appendFixed(":").appendFixed(MapUtils.getString(paramMap,SearchRequestParams.PARAM_SEARCH_NEEDSMALLSORT));//报文
|
|
|
return redisKeyBuilder;
|
|
|
}
|
|
|
} |
...
|
...
|
|