创新实训(47)——在后端项目中使用java API调用ElasticSearch的Suggester实现搜索提示

前言

现在已经建好了相应的索引,现在要使用相应的api实现搜索提示功能。

引入依赖

<dependency>
      <groupId>org.codelibs.fess</groupId>
      <artifactId>fess-suggest</artifactId>
      <version>5.6.0</version>
 </dependency>

使用CompletionSuggester实现搜索提示

之前在建立索引时,设置了五个不同的分词配置,我们可以使用不同的分词配置,对title和content进行匹配,

/*
	1. 全中文词汇 采用ik-word ik分词 和standard 查询。
	2. 含有英文和中文的 采用 s-pinyin keyword_pinyin
	3. 全英文的就使用拼音

处理搜索结果:

    private void handlerSuggest(Suggest suggestions,Map<String,Integer> suggestMap,String suggestName){
        List<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> results = suggestions.getSuggestion(suggestName).getEntries();
        for (Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option> op : results) {
            List<? extends Suggest.Suggestion.Entry.Option> options = op.getOptions();
            for (Suggest.Suggestion.Entry.Option pp : options) {
                if (suggestMap.containsKey(pp.getText().toString())) {
                    suggestMap.put(pp.getText().toString(), suggestMap.get(pp.getText().toString()) + 1);
                } else {
                    suggestMap.put(pp.getText().toString(), 1);
                }
            }
        }
    }

实现搜索:

 /**
     * 实现搜索的提示
     * @param content
     */
    public List<String> querySuggestion(String content)
    {

        String suggestionName = INDEX_NAME +TYPE;
        CompletionSuggestionBuilder sPinyin = SuggestBuilders.completionSuggestion("title.s-pinyin").prefix(content).size(10);
        CompletionSuggestionBuilder standardWord = SuggestBuilders.completionSuggestion("title.standard-word").prefix(content).size(10);
        CompletionSuggestionBuilder keywordPinyin = SuggestBuilders.completionSuggestion("title.keyword-pinyin").prefix(content).size(10);
        CompletionSuggestionBuilder ikWord = SuggestBuilders.completionSuggestion("title.ik-word").prefix(content).size(10);
//        CompletionSuggestionBuilder keywordFirstPy = SuggestBuilders.completionSuggestion("title.keyword-first-py").prefix(content).size(10);

        CompletionSuggestionBuilder ContentsPinyin = SuggestBuilders.completionSuggestion("content.s-pinyin").prefix(content).size(10);
        CompletionSuggestionBuilder ContentstandardWord = SuggestBuilders.completionSuggestion("content.standard-word").prefix(content).size(10);
        CompletionSuggestionBuilder ContentkeywordPinyin = SuggestBuilders.completionSuggestion("content.keyword-pinyin").prefix(content).size(10);
        CompletionSuggestionBuilder ContentikWord = SuggestBuilders.completionSuggestion("content.ik-word").prefix(content).size(10);
//        CompletionSuggestionBuilder ContentkeywordFirstPy = SuggestBuilders.completionSuggestion("content.keyword-first-py").prefix(content).size(10);
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder
                .addSuggestion("s-pinyin", sPinyin)
                .addSuggestion("standard-word", standardWord)
                .addSuggestion("keyword_pinyin", keywordPinyin)
                .addSuggestion("ik-word", ikWord)
//                .addSuggestion("keyword-first-py", keywordFirstPy)
                .addSuggestion("s-pinyin2", ContentsPinyin)
                .addSuggestion("standard-word2", ContentstandardWord)
                .addSuggestion("keyword_pinyin2", ContentkeywordPinyin)
                .addSuggestion("ik-word2", ContentikWord);
//                .addSuggestion("keyword-first-py2", ContentkeywordFirstPy);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.suggest(suggestBuilder);
        searchSourceBuilder
                .fetchSource("content.s-pinyin", null)
                .fetchSource("content.standard-word", null)
                .fetchSource("content.keyword-pinyin", null)
                .fetchSource("content.ik-word", null)
//                .fetchSource("content.keyword-first-py", null)
                .fetchSource("title.s-pinyin", null)
                .fetchSource("title.standard-word", null)
                .fetchSource("title.keyword-pinyin", null)
                .fetchSource("title.ik-word", null);
//                .fetchSource("title.keyword-first-py", null);
        SearchResponse searchResponse = elasticsearchTemplate.suggest(suggestBuilder, INDEX_NAME);
        Suggest suggestions = searchResponse.getSuggest();
        //合并词条
        Map<String,Integer> suggestMap = new LinkedHashMap<>();

        handlerSuggest(suggestions,suggestMap,"ik-word");
        if(suggestMap.size() < 10){
            handlerSuggest(suggestions,suggestMap,"s-pinyin");
            handlerSuggest(suggestions,suggestMap,"keyword_pinyin");
        }
        if(suggestMap.size() == 0){
            handlerSuggest(suggestions,suggestMap,"standard-word");
        }
//        if(suggestMap.size() == 0){
//            handlerSuggest(suggestions,suggestMap,"keyword-first-py");
//        }


		 **/

        List<String> suggestList = new ArrayList<>();
        suggestMap.forEach((key,value)->{
            suggestList.add(key);
        });
        // 自动补全查询不到数据,那么就切换到phrase模式进行匹配,如果再找不到并且性能允许的情况下,切换到term模式.
        if(suggestList.size() == 0)
        {
            phraseSuggestion(content);
        }
        return suggestList;
    }

如果返回的结果为空,则可以使用phrase模式进行匹配,具体的代码还在调试,没有完全的实现。

前端结果为

创新实训(47)——在后端项目中使用java API调用ElasticSearch的Suggester实现搜索提示_第1张图片
创新实训(47)——在后端项目中使用java API调用ElasticSearch的Suggester实现搜索提示_第2张图片
创新实训(47)——在后端项目中使用java API调用ElasticSearch的Suggester实现搜索提示_第3张图片
创新实训(47)——在后端项目中使用java API调用ElasticSearch的Suggester实现搜索提示_第4张图片
创新实训(47)——在后端项目中使用java API调用ElasticSearch的Suggester实现搜索提示_第5张图片
创新实训(47)——在后端项目中使用java API调用ElasticSearch的Suggester实现搜索提示_第6张图片
效果还是可以的,明天要在处理一下如果CompletionSuggestion搜索不出来结果,使用phraseSuggestion

你可能感兴趣的:(项目实训)