本文主要是介绍elasticsearch5.5.2用javaAPI实现搜索结果高亮显示和搜索建议,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言:
像百度、360搜索等等,我们输入完搜索条件时,他会自动出来一个提示框,将我们输入的关键词进行自动补全,即搜索推荐。当我们点击搜索后,返回的搜索结果中会将我们搜索的内容进行高亮的显示(不同颜色标记出来),强大的elasticsearch就提供了这些功能。在这里我会使用javaAPI来介绍一下搜索结果Highlight高亮显示和completion suggest搜索推荐的具体实现,方便以后进行查阅。
源代码下载
一、准备开发环境
该项目基于springboot
1.1jdk1.8
1.2elasticsearch需要用到的maven依赖
<!--es--><dependency><groupId>org.elasticsearch.client</groupId><artifactId>transport</artifactId><version>${elasticsearch.version}</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.7</version></dependency>
1.3elasticsearch的client进行配置,当我们需要用到client的时候直接注入就可以了
@Configuration
public class MyConfig {@Beanpublic TransportClient client() throws UnknownHostException{//配置节点InetSocketTransportAddress node = new InetSocketTransportAddress(InetAddress.getByName("localhost"),9300);//配置settiongSettings settings = Settings.builder().put("cluster.name", "my-application").build();TransportClient client = new PreBuiltTransportClient(settings);client.addTransportAddress(node);return client;}
}
二、搜索结果高亮显示
2.1java代码实现Highlight高亮显示
下边的代码中,涉及了项目中分页的一些代码,如果没有需求直接进行删除就可以了。
/*** 进行搜索* 将结果进行分页* @param title* @return*/@RequestMapping("searchItems")@ResponseBodypublic Map<String,Object> goSearch(@RequestParam(value="title",defaultValue = "") String title,@RequestParam(value="pageNow",defaultValue = "") String PageNow,@RequestParam(value="totalCount",defaultValue = "") String totalCount){//返回的map,进行数据封装Map<String,Object> msgMap = new HashMap<String,Object>();//建立bool查询,如果没有组合查询,直接写QueryBuilderBoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();//使用should实现或者查询boolBuilder.must(QueryBuilders.matchQuery("title",title));//查询总记录数和当前页数long pageSize = 0;if(totalCount != "" && totalCount != null){pageSize = new Long(totalCount);}long pn = 0;if(PageNow != "" && PageNow != null){pn = new Long(PageNow);}Page page = new Page(pageSize,pn);//c查询SearchRequestBuilder searchRequestBuilder = this.client.prepareSearch("testshop").setTypes("item").setSearchType(SearchType.DFS_QUERY_THEN_FETCH) //设置查询类型:1.SearchType.DFS_QUERY_THEN_FETCH 精确查询; 2.SearchType.SCAN 扫描查询,无序.setQuery(boolBuilder).setFrom(new Long(page.getStartPos()).intValue()).setSize(10);//设置高亮显示HighlightBuilder highlightBuilder = new HighlightBuilder().field("*").requireFieldMatch(false);highlightBuilder.preTags("<span style=\"color:red\">");highlightBuilder.postTags("</span>");searchRequestBuilder.highlighter(highlightBuilder);//执行结果SearchResponse response = searchRequestBuilder.get();//接受结果List<Map<String,Object>> result = new ArrayList<>();//遍历结果for(SearchHit hit:response.getHits()){Map<String, Object> source = hit.getSource();//处理高亮片段Map<String, HighlightField> highlightFields = hit.getHighlightFields();HighlightField nameField = highlightFields.get("title");if(nameField!=null){Text[] fragments = nameField.fragments();String nameTmp ="";for(Text text:fragments){nameTmp+=text;}//将高亮片段组装到结果中去source.put("title",nameTmp);}result.add(source);}//封装数据返回msgMap.put("itemsList",result); //搜索结果//msgMap.put("page","page"); //分页msgMap.put("took",response.getTook().getSecondsFrac()); //获取响应需要的时间msgMap.put("total",totalCount); //获得查询的总记录数return msgMap;}
2.2效果展示
实现以下样式,上边的代码是关键,还需要自己写一下前台的js,如果需要源码可以给我留言
三、搜索建议,搜索关键字自动补充
3.1.创建mapping
如果完成搜索建议,需要在mapping中先设置completion
PUT /news_website
{"mappings": {"news" : {"properties" : {"title" : {"type": "text","analyzer": "ik_max_word","fields": {"suggest" : {"type" : "completion","analyzer": "ik_max_word"}}},"content": {"type": "text","analyzer": "ik_max_word"}}}}
}
使用bulk批量插入一些数据,方便我们进行测试
@RequestMapping("bulk")@ResponseBodypublic String insetDate() throws Exception{BulkRequestBuilder bulkRequest = client.prepareBulk();//插入bulkRequest.add(this.client.prepareIndex("news_website", "news", "1").setSource(XContentFactory.jsonBuilder().startObject().field("title","大话西游电影").field("content","大话西游的电影时隔20年即将在2017年4月重映").endObject())); bulkRequest.add(this.client.prepareIndex("news_website", "news", "2").setSource(XContentFactory.jsonBuilder().startObject().field("title","大话西游小说").field("content","某知名网络小说作家已经完成了大话西游同名小说的出版").endObject())); bulkRequest.add(this.client.prepareIndex("news_website", "news", "3").setSource(XContentFactory.jsonBuilder().startObject().field("title","大话西游手游").field("content","网易游戏近日出品了大话西游经典IP的手游,正在火爆内测中").endObject())); //批量执行BulkResponse bulkResponse = bulkRequest.get();//client.close();return bulkResponse.getTook().toString();}
3.2javaAPI实现completion suggest搜索推荐
下边的代码是我项目中的一部分代码,我直接将他搬了过来
/*** 搜索建议* @param tmptitle* @return* @throws UnsupportedEncodingException*/@RequestMapping("suggestion")@ResponseBodypublic Map<String,Object> querySuggestion(@RequestParam(value="tmptitle",defaultValue = "") String tmptitle) throws UnsupportedEncodingException {//返回的map,进行数据封装Map<String,Object> msgMap = new HashMap<String,Object>();//创建需要搜索的inde和typeSearchRequestBuilder requestBuilder = client.prepareSearch("news_website").setTypes("news");//设置搜索建议CompletionSuggestionBuilder completionSuggestionBuilder = new CompletionSuggestionBuilder("title.suggest").prefix(tmptitle).size(10);SuggestBuilder suggestBuilder = new SuggestBuilder().addSuggestion("title.suggest", completionSuggestionBuilder);requestBuilder.suggest(suggestBuilder);//进行搜索SearchResponse suggestResponse = requestBuilder.execute().actionGet();//用来处理的接受结果List<String> result = new ArrayList<>();List<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> entries = suggestResponse.getSuggest().getSuggestion("title.suggest").getEntries();//处理结果for(Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option> op:entries){List<? extends Option> options = op.getOptions();for(Suggest.Suggestion.Entry.Option pp : options){result.add(pp.getText().toString());}}msgMap.put("result",result);return msgMap;}
3.3查看效果
目前还没有将他整合到页面搜索框中,只是实现了功能,当我们输入 “大话”后,他会自动补全:“大话西游电影”,“大话西游手游”,“大话西游小说”。
以上就是对elasticsearch5.5.2版本的高亮显示和搜索建议的java实现,我的其他文章也讲到了elasticsearch其他的一些知识,如果有需要可以翻阅查看,如果有哪些地方有问题,欢迎大家留言指正,感激不尽!
这篇关于elasticsearch5.5.2用javaAPI实现搜索结果高亮显示和搜索建议的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!