|
|
package com.yoho.search.service.helper;
|
|
|
|
|
|
import com.yoho.search.base.constants.ProductModelValueConstants;
|
|
|
import com.yoho.search.base.utils.ConvertUtils;
|
|
|
import com.yoho.search.base.utils.DateUtil;
|
|
|
import com.yoho.search.base.utils.ProductIndexEsField;
|
|
|
import com.yoho.search.common.SearchServiceConfiger;
|
|
|
import com.yoho.search.common.utils.SearchKeyWordUtils;
|
|
|
import com.yoho.search.core.es.model.SearchField;
|
|
|
import com.yoho.search.core.es.utils.SearchFieldUtils;
|
|
|
import com.yoho.search.common.SearchRequestParams;
|
|
|
import org.apache.commons.collections.MapUtils;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
import org.apache.lucene.search.join.ScoreMode;
|
|
|
import org.elasticsearch.index.query.*;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
@Service
|
|
|
public class SearchServiceHelper {
|
|
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(SearchServiceHelper.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);
|
|
|
|
|
|
|
|
|
// //////////////////////////////////////////支持传多个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);
|
|
|
|
|
|
// //////////////////////////////////////////只支持单个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);
|
|
|
|
|
|
|
|
|
// ///////////////////////////////////////////特殊过滤/////////////////////////////////////////////////////////
|
|
|
// 判断是否需要包含全球购[全球购的开关]
|
|
|
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));
|
|
|
}
|
|
|
|
|
|
// 自定义标签
|
|
|
BoolQueryBuilder customizeTagsTermsBuilder = searchCommonHelper.getCustomizeTagBuilder(paramMap);
|
|
|
if (customizeTagsTermsBuilder != null) {
|
|
|
boolFilter.must(QueryBuilders.nestedQuery(ProductIndexEsField.customizeTags, customizeTagsTermsBuilder, ScoreMode.None));
|
|
|
}
|
|
|
|
|
|
// 用户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)) {
|
|
|
int[] commonSortIds = ConvertUtils.stringToIntArray(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.helper;
|
|
|
|
|
|
import com.yoho.search.base.constants.ProductModelValueConstants;
|
|
|
import com.yoho.search.base.utils.ConvertUtils;
|
|
|
import com.yoho.search.base.utils.DateUtil;
|
|
|
import com.yoho.search.base.utils.ProductIndexEsField;
|
|
|
import com.yoho.search.common.SearchServiceConfiger;
|
|
|
import com.yoho.search.common.utils.SearchKeyWordUtils;
|
|
|
import com.yoho.search.core.es.model.SearchField;
|
|
|
import com.yoho.search.core.es.utils.SearchFieldUtils;
|
|
|
import com.yoho.search.common.SearchRequestParams;
|
|
|
import org.apache.commons.collections.MapUtils;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
import org.apache.lucene.search.join.ScoreMode;
|
|
|
import org.elasticsearch.index.query.*;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
// //////////////////////////////////////////支持传多个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);
|
|
|
|
|
|
// //////////////////////////////////////////只支持单个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);
|
|
|
|
|
|
|
|
|
// ///////////////////////////////////////////特殊过滤/////////////////////////////////////////////////////////
|
|
|
// 判断是否需要包含全球购[全球购的开关]
|
|
|
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));
|
|
|
}
|
|
|
|
|
|
// 自定义标签
|
|
|
BoolQueryBuilder customizeTagsTermsBuilder = searchCommonHelper.getCustomizeTagBuilder(paramMap);
|
|
|
if (customizeTagsTermsBuilder != null) {
|
|
|
boolFilter.must(QueryBuilders.nestedQuery(ProductIndexEsField.customizeTags, customizeTagsTermsBuilder, ScoreMode.None));
|
|
|
}
|
|
|
|
|
|
// 用户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)) {
|
|
|
int[] commonSortIds = ConvertUtils.stringToIntArray(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;
|
|
|
}
|
|
|
} |
...
|
...
|
|