|
|
package com.yoho.search.consumer.suggests.counter;
|
|
|
|
|
|
import com.yoho.search.base.utils.ConvertUtils;
|
|
|
import com.yoho.search.base.utils.ISearchConstants;
|
|
|
import com.yoho.search.consumer.index.common.IYohoIndexService;
|
|
|
import com.yoho.search.core.es.agg.IAggregation;
|
|
|
import com.yoho.search.consumer.suggests.common.SuggestSearchParamBuilder;
|
|
|
import com.yoho.search.core.es.model.SearchParam;
|
|
|
import com.yoho.search.core.es.model.SearchResult;
|
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.elasticsearch.index.query.*;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
import org.springframework.util.Assert;
|
...
|
...
|
@@ -27,123 +23,17 @@ public class KeywordCounterService { |
|
|
@Autowired
|
|
|
private IYohoIndexService yohoIndexService;
|
|
|
|
|
|
public Integer countInES(String keyword) {
|
|
|
Assert.notNull(keyword);
|
|
|
SearchParam searchParam = buildSearchParam(keyword);
|
|
|
SearchResult result = yohoIndexService.search(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
|
|
|
return result != null ? Integer.valueOf(String.valueOf(result.getTotal())) : null;
|
|
|
}
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
public Map<String, Integer> batchCountByAgg(IAggregation aggregation) {
|
|
|
SearchParam searchParam = buildSearchParam("");
|
|
|
searchParam.addAbstractAggregationBuilder(aggregation.getBuilder());
|
|
|
SearchResult searchResult = yohoIndexService.search(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
|
|
|
if (searchResult != null) {
|
|
|
return (Map<String, Integer>) aggregation.getAggregationResponseMap(searchResult.getAggMaps());
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
public Map<String, Integer> batchCount(List<String> keywords) {
|
|
|
public Map<String, Integer> batchCount(List<String> keywords, CountUsage countUsage) {
|
|
|
Assert.notNull(keywords);
|
|
|
Map<String, Integer> countResultMap = new LinkedHashMap<>();
|
|
|
List<SearchParam> searchParams = keywords.stream().map(keyword -> buildSearchParam(keyword)).collect(Collectors.toList());
|
|
|
List<SearchParam> searchParams = keywords.stream().map(keyword -> SuggestSearchParamBuilder.build(keyword, countUsage)).collect(Collectors.toList());
|
|
|
List<SearchResult> results = yohoIndexService.multiSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParams);
|
|
|
Assert.notNull(results);
|
|
|
Assert.isTrue(results.size() == keywords.size());
|
|
|
for (int i = 0; i < keywords.size(); i++) {
|
|
|
countResultMap.put(keywords.get(i), Integer.valueOf(String.valueOf(results.get(i).getTotal())));
|
|
|
}
|
|
|
return countResultMap;
|
|
|
}
|
|
|
|
|
|
private SearchParam buildSearchParam(String keyword) {
|
|
|
// TODO: 暂时先从service那边拷贝相关代码 后续考虑抽取到core
|
|
|
SearchParam searchParam = new SearchParam();
|
|
|
searchParam.setQuery(getMultiMatchQueryBuilder(keyword));
|
|
|
searchParam.setFiter(getBoolQueryBuilder(keyword));
|
|
|
searchParam.setSize(0);
|
|
|
return searchParam;
|
|
|
}
|
|
|
|
|
|
private BoolQueryBuilder getBoolQueryBuilder(String keyword) {
|
|
|
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
|
|
|
// 增加默认的过滤条件 TODO: 支持可配置
|
|
|
boolFilter.mustNot(QueryBuilders.termsQuery("isGlobal", "Y")); // 非全球购
|
|
|
boolFilter.mustNot(QueryBuilders.termsQuery("isSeckill", "Y")); // 非秒杀
|
|
|
boolFilter.must(QueryBuilders.rangeQuery("storageNum").gte(1)); // 有库存
|
|
|
boolFilter.mustNot(QueryBuilders.termQuery("attribute", "2")); // 非赠品
|
|
|
boolFilter.must(QueryBuilders.termQuery("status", "1")); // 上架商品
|
|
|
// 1对男女关键字做特殊处理
|
|
|
boolean cotainBoy = keyword.contains("男");
|
|
|
boolean cotainGirl = keyword.contains("女");
|
|
|
// 对性别做特殊处理
|
|
|
String gender = null;
|
|
|
if (cotainBoy && !cotainGirl) {
|
|
|
gender = "1,3";
|
|
|
} else if (!cotainBoy && cotainGirl) {
|
|
|
gender = "2,3";
|
|
|
} else if (cotainBoy && cotainGirl) {
|
|
|
gender = "1,2,3";
|
|
|
}
|
|
|
if (gender != null) {
|
|
|
int[] genders = ConvertUtils.stringToIntArray(gender, ",");
|
|
|
boolFilter.must(QueryBuilders.termsQuery("gender", genders));
|
|
|
}
|
|
|
return boolFilter;
|
|
|
}
|
|
|
|
|
|
private QueryBuilder getMultiMatchQueryBuilder(String keyword) {
|
|
|
if (StringUtils.isEmpty(keyword)) {
|
|
|
return QueryBuilders.matchAllQuery();
|
|
|
}
|
|
|
|
|
|
MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(keyword);
|
|
|
MultiMatchQueryBuilder.Type multiMatchQueryBuilderType = this.getMultiMatchQueryBuilderType();
|
|
|
if (multiMatchQueryBuilderType != null) {
|
|
|
queryBuilder.type(multiMatchQueryBuilderType);
|
|
|
}
|
|
|
|
|
|
setDefaultSearchField(queryBuilder);
|
|
|
if (ISearchConstants.SEARCH_OPERATOR.equalsIgnoreCase("or")) {
|
|
|
queryBuilder.operator(MatchQueryBuilder.Operator.OR);
|
|
|
queryBuilder.minimumShouldMatch(ISearchConstants.SEARCH_MINIMUM_SHOULD_MATCH);
|
|
|
} else {
|
|
|
queryBuilder.operator(MatchQueryBuilder.Operator.AND);
|
|
|
}
|
|
|
return queryBuilder;
|
|
|
}
|
|
|
|
|
|
private MultiMatchQueryBuilder.Type getMultiMatchQueryBuilderType() {
|
|
|
String configMultiMatchQueryType = ISearchConstants.SEARCH_MULTIMATCHQUERY_TYPE;
|
|
|
if (configMultiMatchQueryType.equalsIgnoreCase(MultiMatchQueryBuilder.Type.BEST_FIELDS.name())) {
|
|
|
return MultiMatchQueryBuilder.Type.BEST_FIELDS;
|
|
|
}
|
|
|
if (configMultiMatchQueryType.equalsIgnoreCase(MultiMatchQueryBuilder.Type.MOST_FIELDS.name())) {
|
|
|
return MultiMatchQueryBuilder.Type.MOST_FIELDS;
|
|
|
}
|
|
|
if (configMultiMatchQueryType.equalsIgnoreCase(MultiMatchQueryBuilder.Type.CROSS_FIELDS.name())) {
|
|
|
return MultiMatchQueryBuilder.Type.CROSS_FIELDS;
|
|
|
}
|
|
|
if (configMultiMatchQueryType.equalsIgnoreCase(MultiMatchQueryBuilder.Type.PHRASE.name())) {
|
|
|
return MultiMatchQueryBuilder.Type.PHRASE;
|
|
|
}
|
|
|
if (configMultiMatchQueryType.equalsIgnoreCase(MultiMatchQueryBuilder.Type.PHRASE_PREFIX.name())) {
|
|
|
return MultiMatchQueryBuilder.Type.PHRASE_PREFIX;
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
private void setDefaultSearchField(MultiMatchQueryBuilder queryBuilder) {
|
|
|
List<String> fields = ISearchConstants.SEARCH_DEFAULT_FIELD;
|
|
|
for (String field : fields) {
|
|
|
String[] fieldBoost = field.split("^");
|
|
|
if (fieldBoost.length == 2) {
|
|
|
queryBuilder.field(fieldBoost[0], Float.parseFloat(fieldBoost[1]));
|
|
|
} else if (fieldBoost.length == 1) {
|
|
|
queryBuilder.field(fieldBoost[0]);
|
|
|
}
|
|
|
}
|
|
|
return countResultMap;
|
|
|
}
|
|
|
} |
...
|
...
|
|