package com.winhc.phoenix.example.service.impl; import com.winhc.phoenix.example.dao.SearchDao; import com.winhc.phoenix.example.service.SearchService; import com.winhc.phoenix.example.util.SortUtil; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.elasticsearch.common.lucene.search.function.CombineFunction; import org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery; import org.elasticsearch.index.query.*; import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder; import org.elasticsearch.index.query.functionscore.ScriptScoreFunctionBuilder; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.search.sort.ScriptSortBuilder; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; import java.util.regex.Pattern; import static org.elasticsearch.index.query.QueryBuilders.*; /** * @author: XuJiakai * 2020/11/19 14:54 */ @Slf4j @Primary @Service(value = SearchV8ServiceImpl.index) @AllArgsConstructor public class SearchV8ServiceImpl implements SearchService { private SearchDao searchDao; public static final String index = "winhc-company-v8"; public static final String type = "company"; private static final String[] includes = new String[]{"cname", "legal_entity*", "estiblish_time", "reg_status_std", "company_type", "province_code", "reg_capital", "logo"}; private static final FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, null); private static final String[] includes_tips = new String[]{"cname.show"}; private static final FetchSourceContext fetchSourceContext_tips = new FetchSourceContext(true, includes_tips, null); @Override public Object tips(String content) { BoolQueryBuilder boolQuery = getBoolQuery(content); ScriptSortBuilder scriptSortBuilder = SortUtil.getInstance().fastSort; FunctionScoreQueryBuilder function = functionScoreQuery(boolQuery, new ScriptScoreFunctionBuilder(scriptSortBuilder.script()) ) .scoreMode(FiltersFunctionScoreQuery.ScoreMode.SUM) .boostMode(CombineFunction.MULTIPLY); Object search = searchDao.search(index, type, function, null, fetchSourceContext_tips, 0, 5); return search; } @Override public Object controlGroup(String s) { QueryBuilder boolQuery = getBoolQuery(s); return searchDao.search(index, type, boolQuery, null, fetchSourceContext, 0, 10); } @Override public Object query(String content, int from, int size) { BoolQueryBuilder boolQuery = getBoolQuery(content); ScriptSortBuilder scriptSortBuilder = SortUtil.getInstance().fastSort; FunctionScoreQueryBuilder function = functionScoreQuery(boolQuery, new ScriptScoreFunctionBuilder(scriptSortBuilder.script()) ) .boostMode(CombineFunction.MULTIPLY); Object search = searchDao.search(index, type, function, null, fetchSourceContext, from, size); return search; } private BoolQueryBuilder getBoolQuery(String content) { BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); // boolQuery.should(matchPhrasePrefixQuery("cname.value.pinyin", content).analyzer("ik_pinyin_analyzer_search").maxExpansions(5).boost(0.1F)); boolQuery.should(termQuery("cname.value.keyword", content).boost(100)); boolQuery.should(termQuery("history_name.value.keyword", content).boost(100)); /*boolQuery.should(disMaxQuery().add( QueryBuilders.boolQuery() .should(termQuery("legal_entity_name.keyword", content).boost(10)) .should(termQuery("holder.name.keyword", content).boost(5.5F)) .should(termQuery("staff.name.keyword", content).boost(5.5F)) ).tieBreaker(0.3F));*/ boolQuery.should(disMaxQuery() .add(termQuery("legal_entity_name.keyword", content).boost(10)) .add(termQuery("holder.name.keyword", content).boost(5.5F)) .add(termQuery("staff.name.keyword", content).boost(5.5F)) .tieBreaker(0.3F)); /* boolQuery.should(matchQuery("icp", content).boost(6)); boolQuery.should(matchQuery("app_info", content).boost(12)); boolQuery.should(matchQuery("company_tm", content).boost(5));*/ // boolQuery.should(termQuery("icp.keyword", content).boost(5)); // boolQuery.should(termQuery("app_info.keyword", content).boost(8)); // boolQuery.should(termQuery("company_tm.keyword", content).boost(5)); /* boolQuery.should(disMaxQuery().add( QueryBuilders.boolQuery() .should(termQuery("icp.keyword", content).boost(20)) .should(termQuery("app_info.keyword", content).boost(40)) .should(termQuery("company_tm.keyword", content).boost(20)) ).tieBreaker(0.3F) ); */ /* boolQuery.should(disMaxQuery() .add(termQuery("icp.keyword", content).boost(20)) .add(termQuery("app_info.keyword", content).boost(40)) .add(termQuery("company_tm.keyword", content).boost(20)) .tieBreaker(0.3F) );*/ boolQuery.should(disMaxQuery() .add(disMaxQuery() .add(termQuery("icp.keyword", content).boost(20)) .add(termQuery("app_info.keyword", content).boost(40)) .add(termQuery("company_tm.keyword", content).boost(20)) ) .add( disMaxQuery() .add(matchQuery("icp", content).boost(8).operator(Operator.AND).minimumShouldMatch("5")) .add(matchQuery("app_info", content).boost(19).operator(Operator.AND).minimumShouldMatch("5")) .add(matchQuery("company_tm", content).boost(7).operator(Operator.AND).minimumShouldMatch("5")) .tieBreaker(0.3F) ) /*.add( //todo 在排序上会有影响 ps. 奔驰 boolQuery() .should(matchQuery("icp", content).boost(8)) .should(matchQuery("app_info", content).boost(19)) .should(matchQuery("company_tm", content).boost(7)) .should(termQuery("icp.keyword", content).boost(20)) .should(termQuery("app_info.keyword", content).boost(40)) .should(termQuery("company_tm.keyword", content).boost(20)) .minimumShouldMatch("5<80%") )*/ /*.add( disMaxQuery() .add(boolQuery().should(matchQuery("icp", content).boost(8)).minimumShouldMatch("5<80%")) .add(boolQuery().should(matchQuery("app_info", content).boost(19)).minimumShouldMatch("5<80%")) .add(boolQuery().should(matchQuery("company_tm", content).boost(7)).minimumShouldMatch("5<80%")) .tieBreaker(0.3F) )*/ .tieBreaker(0.4F) ); /* boolQuery.should(disMaxQuery() .tieBreaker(0.3F) .add(matchQuery("icp", content).boost(6).minimumShouldMatch("5<80%")) .add(matchQuery("app_info", content).boost(15).minimumShouldMatch("5<80%")) .add(matchQuery("company_tm", content).boost(5).minimumShouldMatch("5<80%")) .add(termQuery("icp.keyword", content).boost(20)) .add(termQuery("app_info.keyword", content).boost(40)) .add(termQuery("company_tm.keyword", content).boost(30)) );*/ /* boolQuery.should(disMaxQuery() *//* .add( QueryBuilders.boolQuery() .should(matchQuery("icp", content).boost(6)) .should(matchQuery("app_info", content).boost(15)) .should(matchQuery("company_tm", content).boost(5)) .minimumShouldMatch("5<80%") )*//* .add( QueryBuilders.boolQuery() .should(termQuery("icp.keyword", content).boost(20)) .should(termQuery("app_info.keyword", content).boost(40)) .should(termQuery("company_tm.keyword", content).boost(30)) ) .add( multiMatchQuery(content) .operator(Operator.AND) .type(MultiMatchQueryBuilder.Type.CROSS_FIELDS) .minimumShouldMatch("5<90%") .tieBreaker(0.3F) .field("icp", 6) .field("app_info", 15) .field("company_tm", 5) ) .tieBreaker(0.3F) );*/ /* boolQuery.should(multiMatchQuery(content) .operator(Operator.AND) .type(MultiMatchQueryBuilder.Type.CROSS_FIELDS) .tieBreaker(0.3F) .field("icp", 3) .field("app_info", 8) .field("company_tm", 1.5F) );*/ boolQuery.should(multiMatchQuery(content) .operator(Operator.AND) .type(MultiMatchQueryBuilder.Type.CROSS_FIELDS) .minimumShouldMatch("5<80%") .tieBreaker(0.3F) .field("cname.value", 16) .field("history_name.value", 12) .field("holder.name", 6) .field("staff.name", 6) .field("legal_entity_name", 6) ); BoolQueryBuilder boolQuery2 = QueryBuilders.boolQuery(); boolQuery2.must(boolQuery); return boolQuery2; } private static final Pattern pattern = Pattern.compile("^[a-zA-Z ]*$"); private static boolean is_pinyin(String str) { return pattern.matcher(str).find(); } }