elasticsearch5.5.2用javaAPI實現搜尋結果高亮顯示和搜尋建議
阿新 • • 發佈:2018-12-30
前言:
像百度、360搜尋等等,我們輸入完搜尋條件時,他會自動出來一個提示框,將我們輸入的關鍵詞進行自動補全,即搜尋推薦。當我們點選搜尋後,返回的搜尋結果中會將我們搜尋的內容進行高亮的顯示(不同顏色標記出來),強大的elasticsearch就提供了這些功能。在這裡我會使用javaAPI來介紹一下搜尋結果Highlight高亮顯示和completion suggest搜尋推薦的具體實現,方便以後進行查閱。
一、準備開發環境
該專案基於springboot
1.1jdk1.8
1.2elasticsearch需要用到的maven依賴
1.3elasticsearch的client進行配置,當我們需要用到client的時候直接注入就可以了<!--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>
@Configuration public class MyConfig { @Bean public TransportClient client() throws UnknownHostException{ //配置節點 InetSocketTransportAddress node = new InetSocketTransportAddress( InetAddress.getByName("localhost"), 9300 ); //配置settiong Settings 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") @ResponseBody public 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查詢,如果沒有組合查詢,直接寫QueryBuilder BoolQueryBuilder 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")
@ResponseBody
public 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")
@ResponseBody
public Map<String,Object> querySuggestion(
@RequestParam(value="tmptitle",defaultValue = "") String tmptitle
) throws UnsupportedEncodingException {
//返回的map,進行資料封裝
Map<String,Object> msgMap = new HashMap<String,Object>();
//建立需要搜尋的inde和type
SearchRequestBuilder 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其他的一些知識,如果有需要可以翻閱檢視,如果有哪些地方有問題,歡迎大家留言指正,感激不盡!