Authored by wangnan9279

fix

... ... @@ -43,6 +43,7 @@ public class BaseSceneService {
paramMap.put(SearchRequestParams.PARAM_SEARCH_ISLIMITED, "N");// 不支持限定
paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_SECKILL, "N");// 不支持秒杀
paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_GLOBAL, "N");// 不支持全球购
paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_UFO, "N");// 不支持UFO
paramMap.put(SearchRequestParams.PARAM_SEARCH_ISADVANCE, "N");// 不支持预售
paramMap.put(SearchRequestParams.PARAM_SEARCH_BUNDLETYPE, "0");// 不支持套餐
paramMap.put(SearchRequestParams.PARAM_SEARCH_ISLIMITEDBUY, "N");// 不支持限购
... ...
... ... @@ -163,6 +163,8 @@ public class SearchRequestParams {
public static final String UFOPRODUCTINDEX_PARAM_POOL = "pool";
public static final String UFOPRODUCTINDEX_PARAM_IS_SOON_SALE = "isSoonSale";
public static final String UFOPRODUCTINDEX_PARAM_IS_ID_FILTER = "isIdFilter";
// 是否包含UFO
public static final String PARAM_SEARCH_CONTAIN_UFO = "contain_ufo";
// 是否只过滤UFO
public static final String PARAM_SEARCH_IS_UFO = "is_ufo";
}
... ...
... ... @@ -137,6 +137,7 @@ public class RecallResultController {
private void addSortParams(Map<String, String> paramMap) {
addDefaultParamsToParamMap(paramMap);
paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_GLOBAL, "Y");// 包含全球购
paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_UFO, "Y");// 包含全球购
}
private void addNewParams(Map<String, String> paramMap) {
... ...
... ... @@ -180,6 +180,17 @@ public class SearchCommonHelper {
}
/**
* 判断搜索是否需要包含UFO
*/
public boolean containUFO(Map<String, String> paramMap) {
//如果前端传来的参数中不包含contain_ufo!=Y,则不包含ufo
if (!paramMap.containsKey(SearchRequestParams.PARAM_SEARCH_CONTAIN_UFO) || !"Y".equals(paramMap.get(SearchRequestParams.PARAM_SEARCH_CONTAIN_UFO))) {
return false;
}
return true;
}
/**
* 当前查询的关键字是否是skn
*
* @param keyword
... ...
... ... @@ -23,421 +23,428 @@ import java.util.*;
@Service
public class SearchQueryHelper {
private static final Logger logger = LoggerFactory.getLogger(SearchQueryHelper.class);
@Autowired
private SearchCommonHelper searchCommonHelper;
@Autowired
private FunctionScoreSearchHelper functionScoreSearchHelper;
@Autowired
private SearchServiceConfiger configurer;
/**
* 构造关键字查询的query
*
* @param paramMap
* @return
*/
public QueryBuilder constructQueryBuilder(Map<String, String> paramMap) {
// 0、处理查询关键字
String query = SearchKeyWordUtils.getParamKeyword(paramMap, SearchRequestParams.PARAM_SEARCH_QUERY);
if (StringUtils.isBlank(query)) {
return QueryBuilders.matchAllQuery();
}
paramMap.put(SearchRequestParams.PARAM_SEARCH_QUERY, query);
// 1、处理查询中包含性别的情况
searchCommonHelper.dealKeywordOfGender(query, paramMap);
// 2、构建多字段匹配【keyword需要有一个默认的查询字段以及权重设置,就可以拼接成一个sql】
MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(query);
MultiMatchQueryBuilder.Type multiMatchQueryBuilderType = searchCommonHelper.getMultiMatchQueryBuilderType();
if (multiMatchQueryBuilderType != null) {
queryBuilder.type(multiMatchQueryBuilderType);
}
// 3.如果查询的是skn或skuIds,则走productSkn_ansj和skuIds这个字段
if (searchCommonHelper.isQuerySknOrSku(query)) {
queryBuilder.field(ProductIndexEsField.productSkn_productSkn_ansj);
queryBuilder.field(ProductIndexEsField.skuIds);
queryBuilder.operator(Operator.OR);
queryBuilder.minimumShouldMatch("1");
return queryBuilder;
}
// 4.设置查询字段和比重【AND表示多字段都要匹配,可提高精确度】
this.setDefaultSearchField(queryBuilder);
if ("or".equalsIgnoreCase(configurer.getSearchOperator())){
queryBuilder.operator(Operator.OR);
queryBuilder.minimumShouldMatch(configurer.getSearchMinimumShouldMatch());
} else {
queryBuilder.operator(Operator.AND);
}
return queryBuilder;
}
/**
* 构建商品列表的QueryBuilder
*
* @param paramMap
* @return
*/
public QueryBuilder constructQueryBuilderPersional(Map<String, String> paramMap, BoolQueryBuilder filterBuilder) {
QueryBuilder queryBuilder = this.constructQueryBuilder(paramMap);
queryBuilder = functionScoreSearchHelper.buildFunctionScoreQueryBuild(queryBuilder, filterBuilder, paramMap);
return queryBuilder;
}
/**
* 设置默认搜索字段(字段+权重)
*
* @param queryBuilder
*/
private void setDefaultSearchField(MultiMatchQueryBuilder queryBuilder) {
List<SearchField> fuzzySearchFields = SearchFieldUtils.getFuzzySearchFields();
for (SearchField searchField : fuzzySearchFields) {
queryBuilder.field(searchField.getEsField(),searchField.getBoost());
}
}
private boolean checkParamNotFiltered(Map<String, String> paramMap, String filterParamName, String paramName) {
if (!paramMap.containsKey(paramName) || StringUtils.isBlank(paramMap.get(paramName))) {
return false;
}
if (paramMap.get(paramName).equals("null")) {
return false;
}
if (StringUtils.isNotBlank(filterParamName) && paramName.equals(filterParamName)) {
return false;
}
return true;
}
private void addMustIntTermsQuery(BoolQueryBuilder boolFilter,Map<String, String> paramMap, String filterParamName, String paramName,String esField){
if (!this.checkParamNotFiltered(paramMap, filterParamName, paramName)) {
return;
}
List<Integer> values = ConvertUtils.stringToIntList(paramMap.get(paramName), ",");
if(values==null || values.isEmpty()){
return;
}
boolFilter.must(QueryBuilders.termsQuery(esField, values));
}
private void addMustNotIntTermsQuery(BoolQueryBuilder boolFilter,Map<String, String> paramMap, String filterParamName, String paramName,String esField){
if (!this.checkParamNotFiltered(paramMap, filterParamName, paramName)) {
return;
}
List<Integer> values = ConvertUtils.stringToIntList(paramMap.get(paramName), ",");
if(values==null || values.isEmpty()){
return;
}
boolFilter.mustNot(QueryBuilders.termsQuery(esField, values));
}
private void addMustStringTermsQuery(BoolQueryBuilder boolFilter,Map<String, String> paramMap, String filterParamName, String paramName,String esField){
if (!this.checkParamNotFiltered(paramMap, filterParamName, paramName)) {
return;
}
List<String> values = ConvertUtils.stringToStringList(paramMap.get(paramName), ",");
if(values==null || values.isEmpty()){
return;
}
boolFilter.must(QueryBuilders.termsQuery(esField, values));
}
private void addMustStringTermQuery(BoolQueryBuilder boolFilter,Map<String, String> paramMap, String filterParamName, String paramName,String esField){
if (!this.checkParamNotFiltered(paramMap, filterParamName, paramName)) {
return;
}
boolFilter.must(QueryBuilders.termQuery(esField,paramMap.get(paramName)));
}
private void addMustDoubleRangeQuery(BoolQueryBuilder boolFilter,Map<String, String> paramMap, String filterParamName, String paramName,String esField){
if (!this.checkParamNotFiltered(paramMap, filterParamName, paramName)) {
return;
}
List<Double> values = ConvertUtils.stringToDoubleList(paramMap.get(paramName), ",");
if(values==null || values.isEmpty() || values.size()!=2){
return;
}
boolFilter.must(QueryBuilders.rangeQuery(esField).gte(values.get(0)).lte(values.get(1)));
}
/**
* 构造通用的过滤条件
*
* @param paramMap
* @param filterParamName
* (当需要用某个条件聚合时,则此聚合条件不生效)
* @return
* @throws Exception
*/
public BoolQueryBuilder constructFilterBuilder(Map<String, String> paramMap, String filterParamName) throws Exception {
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
// //////////////////////////////////////////支持传多个int参数,以逗号分隔///////////////////////////////////////////////////////////
// 过滤性别
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_GENDER,ProductIndexEsField.gender);
// 过滤品牌
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_BRAND,ProductIndexEsField.brandId);
// 过滤人群
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_AGELEVEL,ProductIndexEsField.ageLevel);
// 过滤颜色
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_COLOR,ProductIndexEsField.colorIds);
// 过滤尺码
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_SIZE,ProductIndexEsField.sizeIds);
// 过滤风格
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_STYLE,ProductIndexEsField.styleIds);
// 过滤大分类
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_MAXSORT,ProductIndexEsField.maxSortId);
// 过滤中分类
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_MIDDLESORT,ProductIndexEsField.middleSortId);
// 过滤小分类
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_SMALLSORT,ProductIndexEsField.smallSortId);
// 过滤店铺
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_SHOP,ProductIndexEsField.shopId);
// 过滤专区标记
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ISPROMOTION,ProductIndexEsField.ispromotion);
// 过滤APP类型
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_APPTYPE,ProductIndexEsField.appType);
// 过滤SKN
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_PRODUCT_SKN,ProductIndexEsField.productSkn);
// 过滤店铺显示状态
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_STORESHOWSTATUS,ProductIndexEsField.storeShowStatus);
// 过滤套餐
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_BUNDLETYPE,ProductIndexEsField.bundleType);
// 过滤vip折扣类型
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_VIPDISCOUNTTYPE,ProductIndexEsField.vipDiscountType);
// 过滤商品属性 1正常商品 2赠品
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ATTRIBUTE,ProductIndexEsField.attribute);
// 过滤状态
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_STATUS,ProductIndexEsField.status);
// 过滤folderId
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_FOLDERID,ProductIndexEsField.folderId);
// 过滤series_id
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_SERIESID,ProductIndexEsField.seriesId);
// 过滤收券限制couponLimitStatus
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_COUPONLIMITSTATUS,ProductIndexEsField.couponLimitStatus);
// 过滤filter_poolId
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_FILTER_POOLID,ProductIndexEsField.poolIds);
// 过滤hrShopIds
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_HR_SHOP,ProductIndexEsField.hrShopIds);
// 过滤hrShopIds
this.addMustIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_COLLAGE_ACTIVITYIDS,ProductIndexEsField.collageActivityIds);
// //////////////////////////////////////////支持传多个int参数,以逗号分隔,must_not///////////////////////////////////////////////////////////
// 专区标记—not
this.addMustNotIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_NOT_PROMOTION,ProductIndexEsField.ispromotion);
// 商品属性-not[1赠品 2正常商品]
this.addMustNotIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ATTRIBUTE_NOT,ProductIndexEsField.attribute);
// 处理not_productSkn
this.addMustNotIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_NOT_PRODUCT_SKN,ProductIndexEsField.productSkn);
// 处理not_brandId
this.addMustNotIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_NOT_BRAND_ID,ProductIndexEsField.brandId);
// 处理not_shopId
this.addMustNotIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_NOT_SHOP_ID,ProductIndexEsField.shopId);
// 优惠价类型
addMustNotIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_COUPONLIMITTYPES,ProductIndexEsField.couponLimitTypes);
//品类id
this.addMustNotIntTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_NOT_MAXSORT_ID,ProductIndexEsField.maxSortId);
// //////////////////////////////////////////只支持单个String参数///////////////////////////////////////////////////////////
// 是否特价
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_SPECIALOFFER,ProductIndexEsField.specialoffer);
// 是否打折
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ISDISCOUNT,ProductIndexEsField.isDiscount);
// 是否为学生价
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_STUDENTPRICE,ProductIndexEsField.isStudentPrice);
// 是否学生返币
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_STUDENTREBATE,ProductIndexEsField.isstudentrebate);
// 是否支持分期
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ISINSTALMENT,ProductIndexEsField.isInstalment);
// 是否在售
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ISSALES,ProductIndexEsField.isSales);
// 是否限量
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ISLIMITED,ProductIndexEsField.islimited);
// 是否限购
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ISLIMITEDBUY,ProductIndexEsField.isLimitbuy);
// 是否预售
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ISADVANCE,ProductIndexEsField.isAdvance);
// 是否定金预售
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ISDESPOSITADVANCE,ProductIndexEsField.isDepositAdvance);
// 是否定金促销
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ISLIMITTIMEADVANCE,ProductIndexEsField.isLimitTimeAdvance);
// 是否新品
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ISNEW,ProductIndexEsField.isnew);
// 是否奥莱
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_ISOUTLETS,ProductIndexEsField.isOutlets);
// 是否全球购
this.addMustStringTermQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_IS_GLOBAL,ProductIndexEsField.isGlobal);
// //////////////////////////////////////////支持传多个String参数,以逗号分隔///////////////////////////////////////////////////////////
// 销售平台 (网站、APP、现场)
this.addMustStringTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_SELLCHANNELS,ProductIndexEsField.sellChannels);
//上架日期
this.addMustStringTermsQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_DAY,ProductIndexEsField.shelveDay);
// //////////////////////////////////////////////////范围过滤////////////////////////////////////////////////////////////
// 销售价格
this.addMustDoubleRangeQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_PRICE,ProductIndexEsField.salesPrice);
// 促销折扣
this.addMustDoubleRangeQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_PD,ProductIndexEsField.promotionDiscount);
// 促销折扣
this.addMustDoubleRangeQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_PDINT,ProductIndexEsField.promotionDiscountInt);
// 首次上架时间间隔
this.addMustDoubleRangeQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_FIRST_SHELVE_TIME,ProductIndexEsField.firstShelveTime);
// 上架日期间隔
this.addMustDoubleRangeQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_SHELVETIME,ProductIndexEsField.shelveTime);
// 价格更新时间
this.addMustDoubleRangeQuery(boolFilter,paramMap,filterParamName,SearchRequestParams.PARAM_SEARCH_PRICE_UPDATE_TIME,ProductIndexEsField.priceUpdateTime);
// 最近一次降价时间
this.addMustDoubleRangeQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_LAST_REDUCE_PRICE_TIME, ProductIndexEsField.lastReducePriceTime);
//店铺创建时间
this.addMustDoubleRangeQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_SHOP_CREATE_TIME, ProductIndexEsField.shopCreateTime);
// ///////////////////////////////////////////特殊过滤/////////////////////////////////////////////////////////
// 判断是否需要包含全球购[全球购的开关]
if (!searchCommonHelper.containGlobal(paramMap)) {
boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isGlobal, "Y"));
}
// 屏蔽页面判断
if ("Y".equals(paramMap.get(SearchRequestParams.PARAM_SEARCH_GLOBAL_FILTER_BRAND)) && StringUtils.isNotBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_PAGEID))) {
boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.forbiddenPageIds, paramMap.get(SearchRequestParams.PARAM_SEARCH_PAGEID)));
}
// 如果contain_seckill!=Y,则过滤掉秒杀商品
if (!MapUtils.getString(paramMap,SearchRequestParams.PARAM_SEARCH_CONTAIN_SECKILL,"N").equalsIgnoreCase("Y")) {
boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isSeckill, "Y"));
}
// 如果contain_fobbiden!=Y,则过滤屏蔽的商品
if (!MapUtils.getString(paramMap,SearchRequestParams.PARAM_SEARCH_CONTAIN_FOBBIDEN,"N").equalsIgnoreCase("Y")) {
boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isFobbiden, 1));
}
// 库存相关的过滤条件
QueryBuilder stocknumberQueryBuilder = this.getStorageNumQueryBuilder(paramMap, filterParamName);
if (stocknumberQueryBuilder != null) {
boolFilter.must(stocknumberQueryBuilder);
}
// 活动模板相关的过滤条件
BoolQueryBuilder activitiesTermsBuilder = searchCommonHelper.getActivitiesTermsBuilder(paramMap);
if (activitiesTermsBuilder != null) {
boolFilter.must(QueryBuilders.nestedQuery(ProductIndexEsField.activities, activitiesTermsBuilder, ScoreMode.None));
}
private static final Logger logger = LoggerFactory.getLogger(SearchQueryHelper.class);
@Autowired
private SearchCommonHelper searchCommonHelper;
@Autowired
private FunctionScoreSearchHelper functionScoreSearchHelper;
@Autowired
private SearchServiceConfiger configurer;
/**
* 构造关键字查询的query
*
* @param paramMap
* @return
*/
public QueryBuilder constructQueryBuilder(Map<String, String> paramMap) {
// 0、处理查询关键字
String query = SearchKeyWordUtils.getParamKeyword(paramMap, SearchRequestParams.PARAM_SEARCH_QUERY);
if (StringUtils.isBlank(query)) {
return QueryBuilders.matchAllQuery();
}
paramMap.put(SearchRequestParams.PARAM_SEARCH_QUERY, query);
// 1、处理查询中包含性别的情况
searchCommonHelper.dealKeywordOfGender(query, paramMap);
// 2、构建多字段匹配【keyword需要有一个默认的查询字段以及权重设置,就可以拼接成一个sql】
MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(query);
MultiMatchQueryBuilder.Type multiMatchQueryBuilderType = searchCommonHelper.getMultiMatchQueryBuilderType();
if (multiMatchQueryBuilderType != null) {
queryBuilder.type(multiMatchQueryBuilderType);
}
// 3.如果查询的是skn或skuIds,则走productSkn_ansj和skuIds这个字段
if (searchCommonHelper.isQuerySknOrSku(query)) {
queryBuilder.field(ProductIndexEsField.productSkn_productSkn_ansj);
queryBuilder.field(ProductIndexEsField.skuIds);
queryBuilder.operator(Operator.OR);
queryBuilder.minimumShouldMatch("1");
return queryBuilder;
}
// 4.设置查询字段和比重【AND表示多字段都要匹配,可提高精确度】
this.setDefaultSearchField(queryBuilder);
if ("or".equalsIgnoreCase(configurer.getSearchOperator())) {
queryBuilder.operator(Operator.OR);
queryBuilder.minimumShouldMatch(configurer.getSearchMinimumShouldMatch());
} else {
queryBuilder.operator(Operator.AND);
}
return queryBuilder;
}
/**
* 构建商品列表的QueryBuilder
*
* @param paramMap
* @return
*/
public QueryBuilder constructQueryBuilderPersional(Map<String, String> paramMap, BoolQueryBuilder filterBuilder) {
QueryBuilder queryBuilder = this.constructQueryBuilder(paramMap);
queryBuilder = functionScoreSearchHelper.buildFunctionScoreQueryBuild(queryBuilder, filterBuilder, paramMap);
return queryBuilder;
}
/**
* 设置默认搜索字段(字段+权重)
*
* @param queryBuilder
*/
private void setDefaultSearchField(MultiMatchQueryBuilder queryBuilder) {
List<SearchField> fuzzySearchFields = SearchFieldUtils.getFuzzySearchFields();
for (SearchField searchField : fuzzySearchFields) {
queryBuilder.field(searchField.getEsField(), searchField.getBoost());
}
}
private boolean checkParamNotFiltered(Map<String, String> paramMap, String filterParamName, String paramName) {
if (!paramMap.containsKey(paramName) || StringUtils.isBlank(paramMap.get(paramName))) {
return false;
}
if (paramMap.get(paramName).equals("null")) {
return false;
}
if (StringUtils.isNotBlank(filterParamName) && paramName.equals(filterParamName)) {
return false;
}
return true;
}
private void addMustIntTermsQuery(BoolQueryBuilder boolFilter, Map<String, String> paramMap, String filterParamName, String paramName, String esField) {
if (!this.checkParamNotFiltered(paramMap, filterParamName, paramName)) {
return;
}
List<Integer> values = ConvertUtils.stringToIntList(paramMap.get(paramName), ",");
if (values == null || values.isEmpty()) {
return;
}
boolFilter.must(QueryBuilders.termsQuery(esField, values));
}
private void addMustNotIntTermsQuery(BoolQueryBuilder boolFilter, Map<String, String> paramMap, String filterParamName, String paramName, String esField) {
if (!this.checkParamNotFiltered(paramMap, filterParamName, paramName)) {
return;
}
List<Integer> values = ConvertUtils.stringToIntList(paramMap.get(paramName), ",");
if (values == null || values.isEmpty()) {
return;
}
boolFilter.mustNot(QueryBuilders.termsQuery(esField, values));
}
private void addMustStringTermsQuery(BoolQueryBuilder boolFilter, Map<String, String> paramMap, String filterParamName, String paramName, String esField) {
if (!this.checkParamNotFiltered(paramMap, filterParamName, paramName)) {
return;
}
List<String> values = ConvertUtils.stringToStringList(paramMap.get(paramName), ",");
if (values == null || values.isEmpty()) {
return;
}
boolFilter.must(QueryBuilders.termsQuery(esField, values));
}
private void addMustStringTermQuery(BoolQueryBuilder boolFilter, Map<String, String> paramMap, String filterParamName, String paramName, String esField) {
if (!this.checkParamNotFiltered(paramMap, filterParamName, paramName)) {
return;
}
boolFilter.must(QueryBuilders.termQuery(esField, paramMap.get(paramName)));
}
private void addMustDoubleRangeQuery(BoolQueryBuilder boolFilter, Map<String, String> paramMap, String filterParamName, String paramName, String esField) {
if (!this.checkParamNotFiltered(paramMap, filterParamName, paramName)) {
return;
}
List<Double> values = ConvertUtils.stringToDoubleList(paramMap.get(paramName), ",");
if (values == null || values.isEmpty() || values.size() != 2) {
return;
}
boolFilter.must(QueryBuilders.rangeQuery(esField).gte(values.get(0)).lte(values.get(1)));
}
/**
* 构造通用的过滤条件
*
* @param paramMap
* @param filterParamName
* (当需要用某个条件聚合时,则此聚合条件不生效)
* @return
* @throws Exception
*/
public BoolQueryBuilder constructFilterBuilder(Map<String, String> paramMap, String filterParamName) throws Exception {
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
// //////////////////////////////////////////支持传多个int参数,以逗号分隔///////////////////////////////////////////////////////////
// 过滤性别
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_GENDER, ProductIndexEsField.gender);
// 过滤品牌
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_BRAND, ProductIndexEsField.brandId);
// 过滤人群
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_AGELEVEL, ProductIndexEsField.ageLevel);
// 过滤颜色
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_COLOR, ProductIndexEsField.colorIds);
// 过滤尺码
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_SIZE, ProductIndexEsField.sizeIds);
// 过滤风格
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_STYLE, ProductIndexEsField.styleIds);
// 过滤大分类
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_MAXSORT, ProductIndexEsField.maxSortId);
// 过滤中分类
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_MIDDLESORT, ProductIndexEsField.middleSortId);
// 过滤小分类
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_SMALLSORT, ProductIndexEsField.smallSortId);
// 过滤店铺
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_SHOP, ProductIndexEsField.shopId);
// 过滤专区标记
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ISPROMOTION, ProductIndexEsField.ispromotion);
// 过滤APP类型
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_APPTYPE, ProductIndexEsField.appType);
// 过滤SKN
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_PRODUCT_SKN, ProductIndexEsField.productSkn);
// 过滤店铺显示状态
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_STORESHOWSTATUS, ProductIndexEsField.storeShowStatus);
// 过滤套餐
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_BUNDLETYPE, ProductIndexEsField.bundleType);
// 过滤vip折扣类型
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_VIPDISCOUNTTYPE, ProductIndexEsField.vipDiscountType);
// 过滤商品属性 1正常商品 2赠品
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ATTRIBUTE, ProductIndexEsField.attribute);
// 过滤状态
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_STATUS, ProductIndexEsField.status);
// 过滤folderId
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_FOLDERID, ProductIndexEsField.folderId);
// 过滤series_id
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_SERIESID, ProductIndexEsField.seriesId);
// 过滤收券限制couponLimitStatus
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_COUPONLIMITSTATUS, ProductIndexEsField.couponLimitStatus);
// 过滤filter_poolId
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_FILTER_POOLID, ProductIndexEsField.poolIds);
// 过滤hrShopIds
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_HR_SHOP, ProductIndexEsField.hrShopIds);
// 过滤hrShopIds
this.addMustIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_COLLAGE_ACTIVITYIDS, ProductIndexEsField.collageActivityIds);
// //////////////////////////////////////////支持传多个int参数,以逗号分隔,must_not///////////////////////////////////////////////////////////
// 专区标记—not
this.addMustNotIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_NOT_PROMOTION, ProductIndexEsField.ispromotion);
// 商品属性-not[1赠品 2正常商品]
this.addMustNotIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ATTRIBUTE_NOT, ProductIndexEsField.attribute);
// 处理not_productSkn
this.addMustNotIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_NOT_PRODUCT_SKN, ProductIndexEsField.productSkn);
// 处理not_brandId
this.addMustNotIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_NOT_BRAND_ID, ProductIndexEsField.brandId);
// 处理not_shopId
this.addMustNotIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_NOT_SHOP_ID, ProductIndexEsField.shopId);
// 优惠价类型
addMustNotIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_COUPONLIMITTYPES, ProductIndexEsField.couponLimitTypes);
//品类id
this.addMustNotIntTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_NOT_MAXSORT_ID, ProductIndexEsField.maxSortId);
// //////////////////////////////////////////只支持单个String参数///////////////////////////////////////////////////////////
// 是否特价
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_SPECIALOFFER, ProductIndexEsField.specialoffer);
// 是否打折
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ISDISCOUNT, ProductIndexEsField.isDiscount);
// 是否为学生价
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_STUDENTPRICE, ProductIndexEsField.isStudentPrice);
// 是否学生返币
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_STUDENTREBATE, ProductIndexEsField.isstudentrebate);
// 是否支持分期
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ISINSTALMENT, ProductIndexEsField.isInstalment);
// 是否在售
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ISSALES, ProductIndexEsField.isSales);
// 是否限量
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ISLIMITED, ProductIndexEsField.islimited);
// 是否限购
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ISLIMITEDBUY, ProductIndexEsField.isLimitbuy);
// 是否预售
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ISADVANCE, ProductIndexEsField.isAdvance);
// 是否定金预售
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ISDESPOSITADVANCE, ProductIndexEsField.isDepositAdvance);
// 是否定金促销
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ISLIMITTIMEADVANCE, ProductIndexEsField.isLimitTimeAdvance);
// 是否新品
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ISNEW, ProductIndexEsField.isnew);
// 是否奥莱
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_ISOUTLETS, ProductIndexEsField.isOutlets);
// 是否全球购
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_IS_GLOBAL, ProductIndexEsField.isGlobal);
// 是否UFO
this.addMustStringTermQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_IS_UFO, ProductIndexEsField.isUfo);
// //////////////////////////////////////////支持传多个String参数,以逗号分隔///////////////////////////////////////////////////////////
// 销售平台 (网站、APP、现场)
this.addMustStringTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_SELLCHANNELS, ProductIndexEsField.sellChannels);
//上架日期
this.addMustStringTermsQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_DAY, ProductIndexEsField.shelveDay);
// //////////////////////////////////////////////////范围过滤////////////////////////////////////////////////////////////
// 销售价格
this.addMustDoubleRangeQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_PRICE, ProductIndexEsField.salesPrice);
// 促销折扣
this.addMustDoubleRangeQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_PD, ProductIndexEsField.promotionDiscount);
// 促销折扣
this.addMustDoubleRangeQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_PDINT, ProductIndexEsField.promotionDiscountInt);
// 首次上架时间间隔
this.addMustDoubleRangeQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_FIRST_SHELVE_TIME, ProductIndexEsField.firstShelveTime);
// 上架日期间隔
this.addMustDoubleRangeQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_SHELVETIME, ProductIndexEsField.shelveTime);
// 价格更新时间
this.addMustDoubleRangeQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_PRICE_UPDATE_TIME, ProductIndexEsField.priceUpdateTime);
// 最近一次降价时间
this.addMustDoubleRangeQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_LAST_REDUCE_PRICE_TIME, ProductIndexEsField.lastReducePriceTime);
//店铺创建时间
this.addMustDoubleRangeQuery(boolFilter, paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_SHOP_CREATE_TIME, ProductIndexEsField.shopCreateTime);
// ///////////////////////////////////////////特殊过滤/////////////////////////////////////////////////////////
// 判断是否需要包含全球购[全球购的开关]
if (!searchCommonHelper.containGlobal(paramMap)) {
boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isGlobal, "Y"));
}
// 判断是否需要包含UFO
if (!searchCommonHelper.containUFO(paramMap)) {
boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isUfo, "Y"));
}
// 屏蔽页面判断
if ("Y".equals(paramMap.get(SearchRequestParams.PARAM_SEARCH_GLOBAL_FILTER_BRAND)) && StringUtils.isNotBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_PAGEID))) {
boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.forbiddenPageIds, paramMap.get(SearchRequestParams.PARAM_SEARCH_PAGEID)));
}
// 如果contain_seckill!=Y,则过滤掉秒杀商品
if (!MapUtils.getString(paramMap, SearchRequestParams.PARAM_SEARCH_CONTAIN_SECKILL, "N").equalsIgnoreCase("Y")) {
boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isSeckill, "Y"));
}
// 如果contain_fobbiden!=Y,则过滤屏蔽的商品
if (!MapUtils.getString(paramMap, SearchRequestParams.PARAM_SEARCH_CONTAIN_FOBBIDEN, "N").equalsIgnoreCase("Y")) {
boolFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isFobbiden, 1));
}
// 库存相关的过滤条件
QueryBuilder stocknumberQueryBuilder = this.getStorageNumQueryBuilder(paramMap, filterParamName);
if (stocknumberQueryBuilder != null) {
boolFilter.must(stocknumberQueryBuilder);
}
// 活动模板相关的过滤条件
BoolQueryBuilder activitiesTermsBuilder = searchCommonHelper.getActivitiesTermsBuilder(paramMap);
if (activitiesTermsBuilder != null) {
boolFilter.must(QueryBuilders.nestedQuery(ProductIndexEsField.activities, activitiesTermsBuilder, ScoreMode.None));
}
// 自定义标签
searchCommonHelper.getCustomizeTagBuilder(paramMap,boolFilter);
// 用户VIP级别过滤
if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_USER_VIP_LEVEL)) {
List<String> userVipLevels = this.getUserVipLevels(paramMap.get(SearchRequestParams.PARAM_SEARCH_USER_VIP_LEVEL));
if (userVipLevels != null) {
boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.vipLevels, userVipLevels));
}
}
// 过滤通用分类
if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_COMMONSORT)) {
List<Integer> commonSortIds = ConvertUtils.stringToIntList(paramMap.get(SearchRequestParams.PARAM_SEARCH_COMMONSORT), ",");
BoolQueryBuilder commonSortIdFilter = QueryBuilders.boolQuery();
commonSortIdFilter.should(QueryBuilders.termsQuery(ProductIndexEsField.maxSortId, commonSortIds));
commonSortIdFilter.should(QueryBuilders.termsQuery(ProductIndexEsField.middleSortId, commonSortIds));
commonSortIdFilter.should(QueryBuilders.termsQuery(ProductIndexEsField.smallSortId, commonSortIds));
boolFilter.must(commonSortIdFilter);
}
// 断码(breakSizePercent>50)
if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_BREAKING) && "1".equals(paramMap.get(SearchRequestParams.PARAM_SEARCH_BREAKING))) {
boolFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.breakSizePercent).gt(50));
}
// 非断码(breakingRate<=50)
if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_BREAKING) && "0".equals(paramMap.get(SearchRequestParams.PARAM_SEARCH_BREAKING))) {
boolFilter.mustNot(QueryBuilders.rangeQuery(ProductIndexEsField.breakSizePercent).gt(50));
}
// 市场推广参数[三高商品或首次上架时间在15天以内]
if ("Y".equals(paramMap.get(SearchRequestParams.PARAM_SEARCH_IS_FOR_MARKET_PROMOTION))) {
BoolQueryBuilder marketPromotionFilter = QueryBuilders.boolQuery();
BoolQueryBuilder modelValuesFilter = QueryBuilders.boolQuery();
modelValuesFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.activeValue, ProductModelValueConstants.getHighValues()));
modelValuesFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.transferValue, ProductModelValueConstants.getHighValues()));
modelValuesFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.giveValue, ProductModelValueConstants.getHighValues()));
modelValuesFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.profitValue, ProductModelValueConstants.getHighAndLowValues()));
Date today = new Date();
long from = DateUtil.getFirstTimeSecond(DateUtil.addDay(today, -15));
long end = DateUtil.getLastTimeSecond(today);
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(ProductIndexEsField.firstShelveTime).from(from).to(end);
marketPromotionFilter.should(modelValuesFilter).should(rangeQueryBuilder);
boolFilter.must(marketPromotionFilter);
}
// 规则
if (!"parameter".equals(filterParamName)) {
Iterator<String> itParamKeys = paramMap.keySet().iterator();
StringBuilder standardValues = new StringBuilder();
while (itParamKeys.hasNext()) {
String paramKey = itParamKeys.next();
if (paramKey.contains("parameter")) {
if (paramKey.contains("_")) {
standardValues.append(",").append(paramKey.split("_")[1]).append(paramMap.get(paramKey));
}
}
}
if (standardValues.length() > 0) {
long[] standards = ConvertUtils.stringToLongArray(standardValues.toString().replaceFirst(",", ""), ",");
for (long standard : standards) {
boolFilter.must(QueryBuilders.termQuery(ProductIndexEsField.standardIds, standard));
}
}
}
if (boolFilter.hasClauses()) {
return boolFilter;
} else {
return null;
}
}
private QueryBuilder getStorageNumQueryBuilder(Map<String, String> paramMap, String filterParamName) {
if (!this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_STOCKNUM)) {
return null;
}
int begin = Integer.parseInt(paramMap.get(SearchRequestParams.PARAM_SEARCH_STOCKNUM));
if (begin == 0) {
return QueryBuilders.termQuery(ProductIndexEsField.storageNum, 0);
}
if (!"1".equals(paramMap.get(SearchRequestParams.PARAM_SEARCH_SHOWSOLDOUT))) {
return QueryBuilders.rangeQuery(ProductIndexEsField.storageNum).gte(begin);
}
// 延期显示[( 库存>=begin) ||(storageNum<begin & storageUpdateTime>now)]
BoolQueryBuilder storageNumFilter = QueryBuilders.boolQuery();
storageNumFilter.should(QueryBuilders.rangeQuery(ProductIndexEsField.storageNum).gte(begin));
storageNumFilter.should(QueryBuilders.boolQuery().must(QueryBuilders.rangeQuery(ProductIndexEsField.storageNum).lt(begin))
.must(QueryBuilders.rangeQuery(ProductIndexEsField.storageUpdateTime).gte(DateUtil.getLastTimeSecond(new Date()))));
return storageNumFilter;
}
private List<String> getUserVipLevels(String userVipLevel) {
if ("1".equals(userVipLevel)) {
return Arrays.asList("1");
}
if ("2".equals(userVipLevel)) {
return Arrays.asList("1", "2");
}
if ("3".equals(userVipLevel)) {
return Arrays.asList("1", "2", "3");
}
return null;
}
searchCommonHelper.getCustomizeTagBuilder(paramMap, boolFilter);
// 用户VIP级别过滤
if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_USER_VIP_LEVEL)) {
List<String> userVipLevels = this.getUserVipLevels(paramMap.get(SearchRequestParams.PARAM_SEARCH_USER_VIP_LEVEL));
if (userVipLevels != null) {
boolFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.vipLevels, userVipLevels));
}
}
// 过滤通用分类
if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_COMMONSORT)) {
List<Integer> commonSortIds = ConvertUtils.stringToIntList(paramMap.get(SearchRequestParams.PARAM_SEARCH_COMMONSORT), ",");
BoolQueryBuilder commonSortIdFilter = QueryBuilders.boolQuery();
commonSortIdFilter.should(QueryBuilders.termsQuery(ProductIndexEsField.maxSortId, commonSortIds));
commonSortIdFilter.should(QueryBuilders.termsQuery(ProductIndexEsField.middleSortId, commonSortIds));
commonSortIdFilter.should(QueryBuilders.termsQuery(ProductIndexEsField.smallSortId, commonSortIds));
boolFilter.must(commonSortIdFilter);
}
// 断码(breakSizePercent>50)
if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_BREAKING) && "1".equals(paramMap.get(SearchRequestParams.PARAM_SEARCH_BREAKING))) {
boolFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.breakSizePercent).gt(50));
}
// 非断码(breakingRate<=50)
if (this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_BREAKING) && "0".equals(paramMap.get(SearchRequestParams.PARAM_SEARCH_BREAKING))) {
boolFilter.mustNot(QueryBuilders.rangeQuery(ProductIndexEsField.breakSizePercent).gt(50));
}
// 市场推广参数[三高商品或首次上架时间在15天以内]
if ("Y".equals(paramMap.get(SearchRequestParams.PARAM_SEARCH_IS_FOR_MARKET_PROMOTION))) {
BoolQueryBuilder marketPromotionFilter = QueryBuilders.boolQuery();
BoolQueryBuilder modelValuesFilter = QueryBuilders.boolQuery();
modelValuesFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.activeValue, ProductModelValueConstants.getHighValues()));
modelValuesFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.transferValue, ProductModelValueConstants.getHighValues()));
modelValuesFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.giveValue, ProductModelValueConstants.getHighValues()));
modelValuesFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.profitValue, ProductModelValueConstants.getHighAndLowValues()));
Date today = new Date();
long from = DateUtil.getFirstTimeSecond(DateUtil.addDay(today, -15));
long end = DateUtil.getLastTimeSecond(today);
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(ProductIndexEsField.firstShelveTime).from(from).to(end);
marketPromotionFilter.should(modelValuesFilter).should(rangeQueryBuilder);
boolFilter.must(marketPromotionFilter);
}
// 规则
if (!"parameter".equals(filterParamName)) {
Iterator<String> itParamKeys = paramMap.keySet().iterator();
StringBuilder standardValues = new StringBuilder();
while (itParamKeys.hasNext()) {
String paramKey = itParamKeys.next();
if (paramKey.contains("parameter")) {
if (paramKey.contains("_")) {
standardValues.append(",").append(paramKey.split("_")[1]).append(paramMap.get(paramKey));
}
}
}
if (standardValues.length() > 0) {
long[] standards = ConvertUtils.stringToLongArray(standardValues.toString().replaceFirst(",", ""), ",");
for (long standard : standards) {
boolFilter.must(QueryBuilders.termQuery(ProductIndexEsField.standardIds, standard));
}
}
}
if (boolFilter.hasClauses()) {
return boolFilter;
} else {
return null;
}
}
private QueryBuilder getStorageNumQueryBuilder(Map<String, String> paramMap, String filterParamName) {
if (!this.checkParamNotFiltered(paramMap, filterParamName, SearchRequestParams.PARAM_SEARCH_STOCKNUM)) {
return null;
}
int begin = Integer.parseInt(paramMap.get(SearchRequestParams.PARAM_SEARCH_STOCKNUM));
if (begin == 0) {
return QueryBuilders.termQuery(ProductIndexEsField.storageNum, 0);
}
if (!"1".equals(paramMap.get(SearchRequestParams.PARAM_SEARCH_SHOWSOLDOUT))) {
return QueryBuilders.rangeQuery(ProductIndexEsField.storageNum).gte(begin);
}
// 延期显示[( 库存>=begin) ||(storageNum<begin & storageUpdateTime>now)]
BoolQueryBuilder storageNumFilter = QueryBuilders.boolQuery();
storageNumFilter.should(QueryBuilders.rangeQuery(ProductIndexEsField.storageNum).gte(begin));
storageNumFilter.should(QueryBuilders.boolQuery().must(QueryBuilders.rangeQuery(ProductIndexEsField.storageNum).lt(begin))
.must(QueryBuilders.rangeQuery(ProductIndexEsField.storageUpdateTime).gte(DateUtil.getLastTimeSecond(new Date()))));
return storageNumFilter;
}
private List<String> getUserVipLevels(String userVipLevel) {
if ("1".equals(userVipLevel)) {
return Arrays.asList("1");
}
if ("2".equals(userVipLevel)) {
return Arrays.asList("1", "2");
}
if ("3".equals(userVipLevel)) {
return Arrays.asList("1", "2", "3");
}
return null;
}
}
... ...
package com.yoho.search.service.index;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.common.SearchCommonService;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import org.apache.commons.collections.MapUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* @author wangnan
* @version 2018/11/13
*/
@Service
public class TblBrandIndexBaseService {
@Autowired
private SearchCommonService searchCommonService;
private static final String TBL_BRAND_INDEX_NAME = ISearchConstants.INDEX_NAME_TBL_BRAND;
public Map<String, Map<String, Object>> getGlobalBrandMapByIds(Collection<?> brandIds, int status) {
List<Map<String, Object>> resultList = this.getGlobalBrandListByIds(brandIds, status);
Map<String, Map<String, Object>> resultMap = new HashMap<String, Map<String, Object>>();
for (Map<String, Object> result : resultList) {
String brand_id = result.get("id").toString();
resultMap.put(brand_id, result);
}
return resultMap;
}
private List<Map<String, Object>> getGlobalBrandListByIds(Collection<?> brandIds, int status) {
if (brandIds == null || brandIds.isEmpty()) {
return new ArrayList<>();
}
SearchParam searchParam = new SearchParam();
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
if (status >= 0) {
boolFilter.must(QueryBuilders.termQuery("status", status));
}
BoolQueryBuilder brandIdFilter = QueryBuilders.boolQuery();
brandIdFilter.should(QueryBuilders.termsQuery("brandId", brandIds));
boolFilter.must(brandIdFilter);
searchParam.setFiter(boolFilter);
searchParam.setOffset(0);
searchParam.setSize(brandIds.size());
SearchResult searchResult = searchCommonService.doSearch(TBL_BRAND_INDEX_NAME, searchParam);
List<Map<String, Object>> esResults = searchResult.getResultList();
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
for (Map<String, Object> esResult : esResults) {
list.add(this.getTblBrandMap(esResult));
}
return list;
}
/**
* 兼容之前返回给前端的字段名
*/
private Map<String, Object> getTblBrandMap(Map<String, Object> esMap) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", MapUtils.getIntValue(esMap, "brandId", 0));
map.put("brand_name", MapUtils.getString(esMap, "brandNameEn", ""));
map.put("brand_name_en", MapUtils.getString(esMap, "brandNameEn", ""));
map.put("brand_name_cn", MapUtils.getString(esMap, "brandNameCn", ""));
map.put("brand_ico", MapUtils.getString(esMap, "logo", ""));
return map;
}
}
... ...
... ... @@ -2,7 +2,11 @@ package com.yoho.search.service.index;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.common.SearchCommonService;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import org.apache.commons.collections.MapUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -29,10 +33,43 @@ public class UfoBrandIndexBaseService {
map.put("brand_name", MapUtils.getString(esMap, "brandName", ""));
map.put("brand_name_en", MapUtils.getString(esMap, "brandNameEn", ""));
map.put("brand_logo", MapUtils.getString(esMap, "brandLogo", ""));
//map.put("status", MapUtils.getIntValue(esMap, "status", 0));
return map;
}
public Map<String, Map<String, Object>> getUfoBrandMapByIds(Collection<?> brandIds, int status) {
List<Map<String, Object>> resultList = this.getUfoBrandListByIds(brandIds, status);
Map<String, Map<String, Object>> resultMap = new HashMap<String, Map<String, Object>>();
for (Map<String, Object> result : resultList) {
String brand_id = result.get("id").toString();
resultMap.put(brand_id, result);
}
return resultMap;
}
private List<Map<String, Object>> getUfoBrandListByIds(Collection<?> brandIds, int status) {
if (brandIds == null || brandIds.isEmpty()) {
return new ArrayList<>();
}
SearchParam searchParam = new SearchParam();
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
if (status >= 0) {
boolFilter.must(QueryBuilders.termQuery("status", status));
}
BoolQueryBuilder brandIdFilter = QueryBuilders.boolQuery();
brandIdFilter.should(QueryBuilders.termsQuery("id", brandIds));
boolFilter.must(brandIdFilter);
searchParam.setFiter(boolFilter);
searchParam.setOffset(0);
searchParam.setSize(brandIds.size());
SearchResult searchResult = searchCommonService.doSearch(UFO_BRAND_INDEX_NAME, searchParam);
List<Map<String, Object>> esResults = searchResult.getResultList();
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
for (Map<String, Object> esResult : esResults) {
list.add(this.getBrandMap(esResult));
}
return list;
}
public List<Map<String, Object>> getBrandListByIds(Collection<?> brandIds) {
List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
try {
... ...
... ... @@ -82,7 +82,9 @@ public class ProductCountService extends AbstractCacheComponent<Long> {
if (!searchCommonHelper.containGlobal(paramMap)) {
mustFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isGlobal, "Y"));
}
if (!searchCommonHelper.containUFO(paramMap)) {
mustFilter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isUfo, "Y"));
}
// 3、构造searchParam
SearchParam searchParam = searchParamHelper.buildWithMustFilter(paramMap, mustFilter);
... ...
... ... @@ -68,6 +68,7 @@ public class FuzzySceneService extends AbstractPageSceneService {
super.addDefaultParamsToParamMap(paramMap);
paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_GLOBAL, "Y");// 包含全球购
paramMap.put(SearchRequestParams.PARAM_SEARCH_NEED_SUGGESTION, "Y");// 返回建议词
paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_UFO, "Y");// 包含UFO
}
/**
... ...
... ... @@ -43,6 +43,7 @@ public class SortPageSceneService extends AbstractPageSceneService {
public void addParamsToParamMap(Map<String, String> paramMap) {
super.addDefaultParamsToParamMap(paramMap);
paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_GLOBAL, "Y");// 包含全球购
paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_UFO, "Y");// 包含UFO
}
private ExecutorService executorService = Executors.newFixedThreadPool(20);
... ...
package com.yoho.search.service.scene.shopbrand;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.aop.cache.SearchCacheAble;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.common.SearchCommonService;
... ... @@ -15,8 +14,9 @@ import com.yoho.search.models.SearchApiResult;
import com.yoho.search.models.SearchSort;
import com.yoho.search.service.helper.AggCommonHelper;
import com.yoho.search.service.helper.SearchCommonHelper;
import com.yoho.search.service.index.BrandIndexBaseService;
import com.yoho.search.service.index.ShopsIndexBaseService;
import com.yoho.search.service.index.TblBrandIndexBaseService;
import com.yoho.search.service.index.UfoBrandIndexBaseService;
import com.yoho.search.service.recall.config.SpecialShopConstants;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.common.lucene.search.function.CombineFunction;
... ... @@ -50,11 +50,13 @@ public class ShopListService {
@Autowired
private ShopsIndexBaseService shopsIndexBaseService;
@Autowired
private BrandIndexBaseService brandIndexBaseService;
private TblBrandIndexBaseService tblBrandIndexBaseService;
@Autowired
private UfoBrandIndexBaseService ufoBrandIndexBaseService;
@Autowired
private SearchCommonHelper searchCommonHelper;
@SearchCacheAble(cacheInMinute = 30, cacheName = "SHOP_LIST", includeParams = {"keyword", "is_encode", "contain_global"})
//@SearchCacheAble(cacheInMinute = 30, cacheName = "SHOP_LIST", includeParams = {"keyword", "is_encode", "contain_global","contain_ufo"})
public SearchApiResult searchShopList(Map<String, String> paramMap) {
// 1、获取搜索店铺的关键词
String keyword = SearchKeyWordUtils.getParamKeyword(paramMap, SearchRequestParams.PARAM_SEARCH_SHOPS_KEYWORD);
... ... @@ -73,9 +75,10 @@ public class ShopListService {
}
queryBuilder.minimumShouldMatch("100%");
// 2.1 全球购得分减半
FilterFunctionBuilder[] filterFunctionBuilders = new FilterFunctionBuilder[2];
FilterFunctionBuilder[] filterFunctionBuilders = new FilterFunctionBuilder[3];
filterFunctionBuilders[0] = new FilterFunctionBuilder(QueryBuilders.termQuery(ProductIndexEsField.isGlobal, "Y"), ScoreFunctionBuilders.weightFactorFunction(0.5f));
filterFunctionBuilders[1] = new FilterFunctionBuilder(QueryBuilders.termQuery(ProductIndexEsField.csBrandKeyword, keyword), ScoreFunctionBuilders.weightFactorFunction(10f));
filterFunctionBuilders[1] = new FilterFunctionBuilder(QueryBuilders.termQuery(ProductIndexEsField.isUfo, "Y"), ScoreFunctionBuilders.weightFactorFunction(0.5f));
filterFunctionBuilders[2] = new FilterFunctionBuilder(QueryBuilders.termQuery(ProductIndexEsField.csBrandKeyword, keyword), ScoreFunctionBuilders.weightFactorFunction(10f));
FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder, filterFunctionBuilders);
functionScoreQueryBuilder.boostMode(CombineFunction.MULTIPLY);
searchParam.setQuery(functionScoreQueryBuilder);
... ... @@ -94,21 +97,36 @@ public class ShopListService {
// 3.2.1 全球购店铺过滤器
BoolQueryBuilder globalShopFilter = QueryBuilders.boolQuery();
globalShopFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.isGlobal, "Y"));
globalShopFilter.must(QueryBuilders.termQuery(ProductIndexEsField.shopId, "0"));
globalShopFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.shopId, "-1"));
// 3.2.2 UFO过滤器
BoolQueryBuilder ufoFilter = QueryBuilders.boolQuery();
ufoFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.isUfo, "Y"));
ufoFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.shopId, "-2"));
// 3.2.2 有货店铺过滤器
BoolQueryBuilder yohoShopFilter = QueryBuilders.boolQuery();
yohoShopFilter.mustNot(QueryBuilders.termsQuery(ProductIndexEsField.isGlobal, "Y"));
yohoShopFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.shopId).gt(0));
// 判断是否需要包含全球购
if (!searchCommonHelper.containGlobal(paramMap)) {
shopFilter.must(yohoShopFilter);
} else {
yohoShopFilter.mustNot(QueryBuilders.termsQuery(ProductIndexEsField.isUfo, "Y"));
yohoShopFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.shopId).gte(0));
// 判断是否需要包含全球购或ufo
boolean containGlobal = searchCommonHelper.containGlobal(paramMap);
boolean containUfo = searchCommonHelper.containUFO(paramMap);
if (containGlobal && containUfo) {
shopFilter.should(yohoShopFilter);
shopFilter.should(globalShopFilter);
shopFilter.should(ufoFilter);
}
boolFilter.must(shopFilter);
searchParam.setFiter(boolFilter);
if (containGlobal && !containUfo) {
shopFilter.should(yohoShopFilter);
shopFilter.should(globalShopFilter);
}
if (!containGlobal && containUfo) {
shopFilter.should(yohoShopFilter);
shopFilter.should(ufoFilter);
}
if (!containGlobal && !containUfo) {
shopFilter.must(yohoShopFilter);
}
searchParam.setFiter(shopFilter);
// 4、构建聚合条件
final String firstAggName = "firstAgg";
SearchSort aggSort = new SearchSort("_score", SortOrder.DESC);
... ... @@ -161,15 +179,21 @@ public class ShopListService {
List<Integer> yohoShopIds = new ArrayList<Integer>();
List<Integer> globalBrandIds = new ArrayList<Integer>();
List<Integer> ufoBrandIds = new ArrayList<Integer>();
for (Map<String, Object> productSource : productSourceList) {
Integer shopId = (Integer) productSource.get(ProductIndexEsField.shopId);
Integer brandId = (Integer) productSource.get(ProductIndexEsField.brandId);
Integer tblBrandId = (Integer) productSource.get(ProductIndexEsField.tblBrandId);
Integer ufoBrandId = (Integer) productSource.get(ProductIndexEsField.ufoBrandId);
String isGlobal = (String) productSource.get(ProductIndexEsField.isGlobal);
if (brandId != null && "Y".equals(isGlobal)) {
globalBrandIds.add(brandId);
String isUfo = (String) productSource.get(ProductIndexEsField.isUfo);
if (tblBrandId != null && "Y".equals(isGlobal) && shopId == -1) {
globalBrandIds.add(tblBrandId);
}
if (ufoBrandId != null && "Y".equals(isUfo) && shopId == -2) {
ufoBrandIds.add(ufoBrandId);
}
if (shopId != null && shopId > 0 && "N".equals(isGlobal)) {
if (shopId != null && "N".equals(isGlobal) && "N".equals(isUfo) && shopId > 0) {
yohoShopIds.add(shopId);
}
}
... ... @@ -180,14 +204,18 @@ public class ShopListService {
// 获取有货状态为1的店铺
Map<String, Map<String, Object>> yohoShopMap = this.queryYohoValidShopMap(yohoShopIds);
Map<String, Map<String, Object>> globalBrandMap = this.queryGlobalValidMap(globalBrandIds);
Map<String, Map<String, Object>> ufoBrandMap = this.queryUfoValidMap(ufoBrandIds);
List<Map<String, Object>> shops_info = new ArrayList<Map<String, Object>>();
for (Map<String, Object> productSource : productSourceList) {
String shopId = productSource.getOrDefault(ProductIndexEsField.shopId, "0").toString();
String brandId = productSource.getOrDefault(ProductIndexEsField.brandId, "0").toString();
String isGlobal = productSource.getOrDefault(ProductIndexEsField.isGlobal, "N").toString();
String isUfo = productSource.getOrDefault(ProductIndexEsField.isUfo, "N").toString();
String tblBrandId = productSource.getOrDefault(ProductIndexEsField.tblBrandId, "0").toString();
String ufoBrandId = productSource.getOrDefault(ProductIndexEsField.ufoBrandId, "0").toString();
Map<String, Object> shop_info = new HashMap<String, Object>();
shop_info.put("tbl_brand", null);
shop_info.put("ufo_brand", null);
shop_info.put("yoho_shop", null);
shop_info.put("_score", 0);
... ... @@ -202,8 +230,8 @@ public class ShopListService {
}
}
// 处理全球购的品牌
if (brandId != null && "Y".equals(isGlobal)) {
Map<String, Object> globalBrand = globalBrandMap.get(brandId);
if (tblBrandId != null && "Y".equals(isGlobal)) {
Map<String, Object> globalBrand = globalBrandMap.get(tblBrandId);
if (globalBrand != null) {
shop_info.put("tbl_brand", globalBrand);
shop_info.put("_score", productSource.getOrDefault("_score", 0));
... ... @@ -211,6 +239,16 @@ public class ShopListService {
continue;
}
}
// 处理UFO品牌
if (ufoBrandId != null && "Y".equals(isUfo)) {
Map<String, Object> ufoBrand = ufoBrandMap.get(ufoBrandId);
if (ufoBrand != null) {
shop_info.put("ufo_brand", ufoBrand);
shop_info.put("_score", productSource.getOrDefault("_score", 0));
shops_info.add(shop_info);
continue;
}
}
}
Collections.sort(shops_info, new Comparator<Map<String, Object>>() {
@SuppressWarnings("unchecked")
... ... @@ -260,13 +298,25 @@ public class ShopListService {
* @return
*/
private Map<String, Map<String, Object>> queryGlobalValidMap(List<Integer> globalBrandIds) {
Map<String, Map<String, Object>> results = brandIndexBaseService.getGlobalBrandMapByIds(globalBrandIds, 1);
//全球购品牌,状态是2的是有效的
Map<String, Map<String, Object>> results = tblBrandIndexBaseService.getGlobalBrandMapByIds(globalBrandIds, 2);
if (results.isEmpty()) {
return results;
}
for (Map<String, Object> globalBrand : results.values()) {
globalBrand.put("search_show_image","");
globalBrand.put("shop_intro","品牌官方授权");
globalBrand.put("search_show_image", "");
globalBrand.put("shop_intro", "品牌官方授权");
}
return results;
}
/**
* 获取有效的ufo的品牌
*/
private Map<String, Map<String, Object>> queryUfoValidMap(List<Integer> ufoBrandIds) {
Map<String, Map<String, Object>> results = ufoBrandIndexBaseService.getUfoBrandMapByIds(ufoBrandIds, 1);
if (results.isEmpty()) {
return results;
}
return results;
}
... ...