日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

elasticsearch搜素关键字自动补全(suggest)

發布時間:2023/12/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 elasticsearch搜素关键字自动补全(suggest) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

elasticsearch搜素關鍵字自動補全顧名思義 在搜索框搜索時能有提示列表可供選擇。

最終效果如下:

該搜索優化功能是elasticsearch自帶的即suggest,suggest即存儲一個詞庫,每次搜索發送請求去詞庫中檢索,匹配到即返回。

接下來我們一步一步實現上述功能。

1.建立索引

我這預先準備了一個房屋信息的索引house

{"settings": {"number_of_replicas": 0},"mappings": {"house": {"dynamic": false,"properties": {"houseId": {"type": "long"},"title": {"type": "text","index": "analyzed","analyzer": "ik_smart","search_analyzer": "ik_smart"},"price": {"type": "integer"},"area": {"type": "integer"},"createTime": {"type": "date","format": "strict_date_optional_time||epoch_millis"},"lastUpdateTime": {"type": "date","format": "strict_date_optional_time||epoch_millis"},"cityEnName": {"type": "keyword"},"regionEnName": {"type": "keyword"},"direction": {"type": "integer"},"distanceToSubway": {"type": "integer"},"subwayLineName": {"type": "keyword"},"subwayStationName": {"type": "keyword"},"tags": {"type": "text"},"street": {"type": "keyword"},"district": {"type": "keyword"},"description": {"type": "text","index": "analyzed","analyzer": "ik_smart","search_analyzer": "ik_smart"},"layoutDesc": {"type": "text","index": "analyzed","analyzer": "ik_smart","search_analyzer": "ik_smart"},"traffic": {"type": "text","index": "analyzed","analyzer": "ik_smart","search_analyzer": "ik_smart"},"roundService": {"type": "text","index": "analyzed","analyzer": "ik_smart","search_analyzer": "ik_smart"},"rentWay": {"type": "integer"},"suggest": {"type": "completion"},"room": {"type": "integer"}}}} }

注意關鍵字段suggest,type為completion

2.向建好的索引中添加數據

主要注意suggest字段中如何添加數據

private boolean updateSuggest(HouseIndexTemplate indexTemplate) {//將分詞字段加入AnalyzeRequestBuilder,通過ik_smart分詞后會生成多個詞組,然后將詞組加入suggest字段AnalyzeRequestBuilder requestBuilder = new AnalyzeRequestBuilder(this.esClient, AnalyzeAction.INSTANCE, INDEX_NAME, indexTemplate.getTitle(),indexTemplate.getLayoutDesc(), indexTemplate.getRoundService(),indexTemplate.getDescription(), indexTemplate.getSubwayLineName(),indexTemplate.getSubwayStationName());//采用ik_smart分詞requestBuilder.setAnalyzer("ik_smart");AnalyzeResponse response = requestBuilder.get();List<AnalyzeResponse.AnalyzeToken> tokens = response.getTokens();if (tokens == null) {logger.warn("Can not analyze token for house: " + indexTemplate.getHouseId());return false;}List<HouseSuggest> suggests = new ArrayList<>();for (AnalyzeResponse.AnalyzeToken token : tokens) {// 排序數字類型 & 小于2個字符的分詞結果if ("<NUM>".equals(token.getType()) || token.getTerm().length() < 2) {continue;}HouseSuggest suggest = new HouseSuggest();suggest.setInput(token.getTerm());suggests.add(suggest);}// 定制化小區自動補全(不需要分詞的字段手動額外加入)HouseSuggest suggest = new HouseSuggest();suggest.setInput(indexTemplate.getDistrict());suggests.add(suggest);indexTemplate.setSuggest(suggests);return true;}

如上代碼表示:

首先將title、layoutDesc、roundService、description、subwayLineName、subwayStationName通過ik_smart分詞后,將分詞后的字詞加入suggests 集合;

然后將不需要分詞的字段district手動加入suggests集合;

其中HouseIndexTemplate 只是一個索引對象,里面封裝了索引所需字段,注意其中suggest為 集合:

private List<HouseSuggest> suggest;

最后將HouseIndexTemplate對象寫入elasticsearch中即可。

IndexResponse response = this.esClient.prepareIndex(INDEX_NAME, INDEX_TYPE).setSource(objectMapper.writeValueAsBytes(indexTemplate), XContentType.JSON).get();

寫入后結構如下 :

3.開始做檢索

前端js調用檢索接口

$('#keyword-box').autocomplete({minLength: 2, // 最小字符數,默認1delay: 300, // 延遲加載300mssource: function (request, response) { // 數據源$.ajax({url: '/rent/house/autocomplete?prefix=' + request.term,success: function (res) {if (res.code === 200) {response(res.data);}}});},select: function (event, ui) { // 選中事件$('#keyword-box').text(ui.item.value);window.location.href = locate_url(start, size);}});

后端接口和服務層:

controller:

/*** 自動補全接口*/@GetMapping("rent/house/autocomplete")@ResponseBodypublic ApiResponse autocomplete(@RequestParam(value = "prefix") String prefix) {if (prefix.isEmpty()) {return ApiResponse.ofStatus(ApiResponse.Status.BAD_REQUEST);}ServiceResult<List<String>> result = this.searchService.suggest(prefix);return ApiResponse.ofSuccess(result.getResult());}

service:

@Overridepublic ServiceResult<List<String>> suggest(String prefix) {CompletionSuggestionBuilder suggestion = SuggestBuilders.completionSuggestion("suggest").prefix(prefix).size(5);SuggestBuilder suggestBuilder = new SuggestBuilder();suggestBuilder.addSuggestion("autocomplete", suggestion);SearchRequestBuilder requestBuilder = this.esClient.prepareSearch(INDEX_NAME).setTypes(INDEX_TYPE).suggest(suggestBuilder);logger.debug(requestBuilder.toString());SearchResponse response = requestBuilder.get();Suggest suggest = response.getSuggest();if (suggest == null) {return ServiceResult.of(new ArrayList<>());}Suggest.Suggestion result = suggest.getSuggestion("autocomplete");int maxSuggest = 0;Set<String> suggestSet = new HashSet<>();for (Object term : result.getEntries()) {if (term instanceof CompletionSuggestion.Entry) {CompletionSuggestion.Entry item = (CompletionSuggestion.Entry) term;if (item.getOptions().isEmpty()) {continue;}for (CompletionSuggestion.Entry.Option option : item.getOptions()) {String tip = option.getText().string();if (suggestSet.contains(tip)) {continue;}suggestSet.add(tip);maxSuggest++;}}if (maxSuggest > 5) {break;}}List<String> suggests = Lists.newArrayList(suggestSet.toArray(new String[]{}));return ServiceResult.of(suggests);}

?

總結

以上是生活随笔為你收集整理的elasticsearch搜素关键字自动补全(suggest)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。