java基础之----elasticsearch(Java客服端搜索实例)
Posted 猿起缘灭
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java基础之----elasticsearch(Java客服端搜索实例)相关的知识,希望对你有一定的参考价值。
概述
es是使用Java编写的,对Java原生比较支持,下面是使用Java写的一个demo,根据关键字进行搜索,并对搜索结果重排序,对部分字段惊醒高亮处理。
public class EsIndexService { protected Logger logger = LoggerFactory.getLogger(getClass()); public static final String SCS_WEB_INDEX = "scs_web"; public static final String QUESTION_TYPE = "question"; public static final String QUESTION_PAIR_TYPE = "question_pair"; public static final String DELETED_FLAG = "1"; public static final String FIELD_CONTENT = "content"; public static final String FIELD_ANSWER = "answer"; public static final String FIELD_HRELATION_TYPE = "hRelation.relationType"; public static final String FIELD_MRELATION_TYPE = "mRelation.relationType"; public static final String FIELD_QUESTION1_ID = "question1.id"; public static final String FIELD_QUESTION2_ID = "question2.id"; public static final String FIELD_HRELATION_START_DATE = "hRelation.startDate"; public static final String FIELD_HRELATION_EXPIRE_DATE = "hRelation.expireDate"; public static final String FIELD_SCORE = "score"; public static final String FIELD_COUNT = "count"; public static final Float COUNT_FACTOR = 0.1f; @Autowired private QuestionDao questionDao; @Autowired private QuestionPairDao questionPairDao; @Autowired private DataSourceTransactionManager transactionManager; @Autowired private SearchLogDao searchLogDao; public Page<QuestionSearchResult> searchQuestion(Question question) throws IOException { //搜索问题为空直接返回 if (StringUtils.isEmpty(question.getContent())) return emptyResult(question); //es原始搜索 MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(FIELD_CONTENT, question.getContent()); //开启模糊匹配 matchQueryBuilder.fuzziness(Fuzziness.AUTO); //对原始结果进行重排序,采用的公式为newScore = oldScore + log(1 + 0.1*count),启动count为数据库中一个字段,意思是点击次数,这个优化的目的就是让点击数大的排在前面 ScoreFunctionBuilder scoreFunctionBuilder = ScoreFunctionBuilders. fieldValueFactorFunction(FIELD_COUNT).factor(COUNT_FACTOR).modifier(FieldValueFactorFunction.Modifier.LOG1P); FunctionScoreQueryBuilder queryBuilder = QueryBuilders.functionScoreQuery(matchQueryBuilder, scoreFunctionBuilder); //这个就是采用oldScore + log(1 + 0.1*count),控制中间的加号的,默认是multiply,就是相乘 queryBuilder.boostMode(CombineFunction.SUM); return searchQuestion(question, queryBuilder, null, null); } public Page<QuestionSearchResult> topByCount(Question question) throws IOException { return searchQuestion(question, null, FIELD_COUNT, SortOrder.DESC); } public Page<QuestionSearchResult> searchQuestion(Question question, QueryBuilder queryBuilder, String orderBy, SortOrder order) throws IOException { Page<QuestionSearchResult> resultPage = emptyResult(question); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.trackScores(true); //进行分页的操作,这个是设置每页的大小 searchSourceBuilder.size(question.getPage().getPageSize()); if (question.getPage().getPageNo() > 1) { //设置从哪里开始搜索 searchSourceBuilder.from((question.getPage().getPageNo() - 1) * question.getPage().getPageSize()); } if (queryBuilder != null) searchSourceBuilder.query(queryBuilder); if (StringUtils.isNotEmpty(orderBy)) searchSourceBuilder.sort(orderBy, order); //高亮 HighlightBuilder highlightBuilder = new HighlightBuilder(); //高亮的结果会使用<em>中间是需要高亮的数据</em>括住 highlightBuilder.field(FIELD_CONTENT).field(FIELD_ANSWER).requireFieldMatch(false); searchSourceBuilder.highlighter(highlightBuilder); SearchRequest searchRequest = new SearchRequest(SCS_WEB_INDEX); searchRequest.types(QUESTION_TYPE); searchRequest.source(searchSourceBuilder); SearchResponse response = EsUtil.client.search(searchRequest); logger.info("搜索问题[{}],结果:{}条,最高score:{},耗时:{}ms", question.getContent(), response.getHits().totalHits, response.getHits().getMaxScore(), response.getTookInMillis()); int maxResultCount = Integer.parseInt(DictUtils.getDictValue("max_result_count", "scs_config", "30")); resultPage.setCount(response.getHits().totalHits > maxResultCount ? maxResultCount : response.getHits().totalHits); if (response.getHits().totalHits < 1) { return resultPage; } BigDecimal maxScore = BigDecimal.valueOf(response.getHits().getMaxScore()); for (SearchHit hit : response.getHits()) { QuestionSearchResult tmp = new QuestionSearchResult(); tmp.setSimilarQuestion((Question) JsonMapper.fromJsonString(hit.getSourceAsString(), Question.class)); BigDecimal currentDocScore = BigDecimal.valueOf(hit.getScore()); tmp.setEsScore(currentDocScore.divide(maxScore, 4, BigDecimal.ROUND_HALF_EVEN)); logger.debug("搜索结果 score: {}, question: {}, count:{}, id: {}", hit.getScore(), tmp.getSimilarQuestion().getContent(), tmp.getSimilarQuestion().getCount(), hit.getId()); List<StringHighlightField> highlightList = new ArrayList<>(); for (String key : hit.getHighlightFields().keySet()) { highlightList.add(StringHighlightField.fromHighlightField(hit.getHighlightFields().get(key))); } tmp.setHighlightList(highlightList); resultPage.getList().add(tmp); } searchLogDao.insert(question.getContent(), response.getHits().getTotalHits()); return resultPage; }
以上是关于java基础之----elasticsearch(Java客服端搜索实例)的主要内容,如果未能解决你的问题,请参考以下文章
原创大数据基础之Ambari通过Ambari部署ElasticSearch
3.高并发教程-基础篇-之分布式全文搜索引擎elasticsearch的搭建