Authored by hugufei

搜索权重支持配置

... ... @@ -9,6 +9,7 @@ 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.service.index.SearchFieldBoostConfigService;
import com.yoho.search.service.scene.searchlabel.ProductSearchLabelIndexBaseService;
import com.yoho.search.service.scene.searchlabel.SearchLabelBO;
import org.apache.commons.collections.CollectionUtils;
... ... @@ -36,25 +37,8 @@ public class SearchQueryHelper {
private SearchServiceConfiger configurer;
@Autowired
private ProductSearchLabelIndexBaseService productSearchLabelIndexBaseService;
public List<SearchField> queryFuzzySearchFields(){
List<SearchField> searchFields = new ArrayList<>(SearchFieldUtils.getFuzzySearchFields());
Map<String,Integer> searchFieldBoostConfig = new HashMap<>();
Iterator<SearchField> iterator = searchFields.iterator();
while (iterator.hasNext()){
SearchField searchField = iterator.next();
Integer boost = searchFieldBoostConfig.get(searchField.getEsField());
if(boost==null){
continue;
}
if(boost<=0){
iterator.remove();
continue;
}
searchField.setBoost(boost);
}
return searchFields;
}
@Autowired
private SearchFieldBoostConfigService searchFieldBoostConfigService;
/**
* 构造关键字查询的query
... ... @@ -91,7 +75,7 @@ public class SearchQueryHelper {
}
// 4.设置查询字段和比重【AND表示多字段都要匹配,可提高精确度】
List<SearchField> fuzzySearchFields = this.queryFuzzySearchFields();
List<SearchField> fuzzySearchFields = searchFieldBoostConfigService.queryFuzzySearchFields(true);
for (SearchField searchField : fuzzySearchFields) {
queryBuilder.field(searchField.getEsField(), searchField.getBoost());
}
... ...
package com.yoho.search.service.index;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.common.SearchCommonService;
import com.yoho.search.core.es.model.SearchField;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.core.es.utils.SearchFieldUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Component
public class SearchFieldBoostConfigService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private static final String CACHE_KEY = "SearchFieldBoostConfigCacheKey";
@Autowired
private SearchCommonService searchCommonService;
//Guava Cache
private LoadingCache<String, Map<String, SearchField>> searchFieldBoostConfigCache = CacheBuilder.newBuilder()
.maximumSize(100).expireAfterWrite(1, TimeUnit.MINUTES).build(new CacheLoader<String, Map<String, SearchField>>() {
public Map<String, SearchField> load(String key) {
return querySearchFieldBoostConfig();
}
});
private Map<String, SearchField> querySearchFieldBoostConfig() {
try {
//1、构造返回参数
SearchParam searchParam = new SearchParam();
searchParam.setOffset(0);
searchParam.setSize(1000);
//2、执行搜索
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_CS_SEARCH_FIELD_BOOST_CONFIG, searchParam);
//3、构造返回结果
List<Map<String, Object>> results = searchResult.getResultList();
if (CollectionUtils.isEmpty(results)) {
return new HashMap<>();
}
Map<String, SearchField> result = new HashMap<>();
for (Map<String, Object> esMap : results) {
SearchField searchField = this.getSearchField(esMap);
result.put(searchField.getEsField(), searchField);
}
return result;
} catch (Exception e) {
logger.error(e.getMessage());
return new HashMap<>();
}
}
private SearchField getSearchField(Map<String, Object> esMap) {
SearchField searchField = new SearchField();
searchField.setEsField(MapUtils.getString(esMap, "field", ""));
searchField.setEsFieldDesc(MapUtils.getString(esMap, "fieldDes", ""));
searchField.setBoost(MapUtils.getInteger(esMap, "boost", 0));
return searchField;
}
private Map<String, SearchField> getSearchFieldBoostConfig(boolean useCache) {
try {
if(useCache){
return searchFieldBoostConfigCache.get(CACHE_KEY);
}else{
return querySearchFieldBoostConfig();
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new HashMap<>();
}
}
public List<SearchField> queryFuzzySearchFields(boolean useCache) {
List<SearchField> searchFields = new ArrayList<>(SearchFieldUtils.getFuzzySearchFields());
Map<String, SearchField> searchFieldMap = getSearchFieldBoostConfig(useCache);
Iterator<SearchField> iterator = searchFields.iterator();
while (iterator.hasNext()) {
SearchField searchField = iterator.next();
SearchField searchFieldConfig = searchFieldMap.get(searchField.getEsField());
if (searchFieldConfig == null || searchFieldConfig.getBoost() == null) {
continue;
}
if (searchFieldConfig.getBoost() <= 0) {
iterator.remove();
continue;
}
searchField.setBoost(searchFieldConfig.getBoost());
searchField.setEsFieldDesc(searchFieldConfig.getEsFieldDesc());
}
return searchFields;
}
}
... ...
package com.yoho.search.service.scene.others.explain;
import java.util.HashSet;
import java.util.Set;
public class FieldDesc {
String field;
String type;
Boolean index;
String analyzer;
String search_analyzer;
Set<String> copy_to = new HashSet<>();
public void addCopyTo(String item) {
copy_to.add(item);
}
public boolean noNeedAnalyzer() {
if (index == null) {
return false;
}
if (index == Boolean.TRUE) {
return false;
}
if ("text".equals(type)) {
return false;
}
return true;
}
@Override
public String toString() {
return "FieldDesc{" + "type='" + type + '\'' + ", index='" + index + '\'' + ", analyzer='" + analyzer + '\'' + ", search_analyzer='" + search_analyzer + '\'' + '}';
}
}
... ...
... ... @@ -12,6 +12,7 @@ import com.yoho.search.core.es.model.SearchField;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.service.helper.SearchQueryHelper;
import com.yoho.search.service.index.SearchFieldBoostConfigService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse;
... ... @@ -44,7 +45,7 @@ public class SearchExplainerService {
@Autowired
private SearchServiceConfiger searchServiceConfiger;
@Autowired
private SearchQueryHelper searchQueryHelper;
private SearchFieldBoostConfigService searchFieldBoostConfigService;
private static final String DEFAULT_ANALYZER = "keyword";
... ... @@ -201,7 +202,7 @@ public class SearchExplainerService {
private SearchFieldResult showSingleField(SearchField fieldWithBoost, Object fieldValue, FieldDesc fieldDesc) throws Exception {
SearchFieldResult searchFieldResult = new SearchFieldResult();
searchFieldResult.setFieldName(fieldWithBoost.esField);
searchFieldResult.setFieldName(fieldWithBoost.getEsField());
searchFieldResult.setBoost(fieldWithBoost.getBoost());
searchFieldResult.setIndexAnalyzer(fieldDesc.analyzer);
searchFieldResult.setSearchAnalyzer(fieldDesc.search_analyzer);
... ... @@ -677,7 +678,7 @@ public class SearchExplainerService {
}
private List<SearchField> getMutilFieldWithBoostList() {
List<SearchField> searchFields = searchQueryHelper.queryFuzzySearchFields();
List<SearchField> searchFields = searchFieldBoostConfigService.queryFuzzySearchFields(false);
Collections.sort(searchFields);
return searchFields;
}
... ... @@ -686,42 +687,11 @@ public class SearchExplainerService {
List<String> result = new ArrayList<>();
List<SearchField> mutilFieldWithBoostList = this.getMutilFieldWithBoostList();
for (SearchField item : mutilFieldWithBoostList) {
result.add(item.esField);
result.add(item.getEsField());
}
return result;
}
static class FieldDesc {
String field;
String type;
Boolean index;
String analyzer;
String search_analyzer;
Set<String> copy_to = new HashSet<>();
public void addCopyTo(String item) {
copy_to.add(item);
}
public boolean noNeedAnalyzer() {
if (index == null) {
return false;
}
if (index == Boolean.TRUE) {
return false;
}
if ("text".equals(type)) {
return false;
}
return true;
}
@Override
public String toString() {
return "FieldDesc{" + "type='" + type + '\'' + ", index='" + index + '\'' + ", analyzer='" + analyzer + '\'' + ", search_analyzer='" + search_analyzer + '\'' + '}';
}
}
public Map<String, Object> multiFieldAnalyzeList(Map<String, String> paramMap) throws Exception {
Map<String, Object> map = new LinkedHashMap<>();
String skn = paramMap.get("skn");
... ... @@ -777,7 +747,7 @@ public class SearchExplainerService {
List<SearchFieldResult> searchFieldResultList = new ArrayList<>();
List<SearchField> mutilFieldWithBoostList = this.getMutilFieldWithBoostList();
Map<String, SearchField> localMutilFieldWithBoostMap = mutilFieldWithBoostList.stream().collect(Collectors.toMap((e -> e.esField), p -> p));
Map<String, SearchField> localMutilFieldWithBoostMap = mutilFieldWithBoostList.stream().collect(Collectors.toMap((e -> e.getEsField()), p -> p));
multiMatchFieldAnalyzeFieldsMap.entrySet().forEach(e -> {
List<FieldDesc> analyzeFields = e.getValue();
List<String> fieldValueList = analyzeFields.stream().map(f -> document.get(f.field).toString()).collect(Collectors.toList());
... ...