springboot集成Elasticsearch实现搜索提示

es7.4 默认不在支持指定索引类型,默认索引类型是_doc(隐含:include_type_name=false)

PUT /news_website
{
  "mappings": {
      "properties" : {
        "title" : {
          "type": "text",
          "analyzer": "ik_max_word",
          "fields": {
            "suggest" : {
              "type" : "completion",
              "analyzer": "ik_max_word"
            }
          }
        },
        "content": {
          "type": "text",
          "analyzer": "ik_max_word"
        }
      }
  }
}

首先查看索引库的mapping

 

第一种方式:基于completion suggest

测试代码如下:

@Test
    public void testSuggestCompletionProc() {

        String suggestField="title.suggest";//指定在哪个字段搜索
        String suggestValue="西游";//输入的信息
        Integer suggestMaxCount=2;//获得最大suggest条数

        CompletionSuggestionBuilder suggestionBuilderDistrict = new CompletionSuggestionBuilder(suggestField).prefix(suggestValue).size(suggestMaxCount);
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder.addSuggestion("student_suggest", suggestionBuilderDistrict);//添加suggest

        //设置查询builder的index,type,以及建议
        SearchRequestBuilder requestBuilder = template.getClient().prepareSearch("news_website")
                .setTypes("news").suggest(suggestBuilder);
        System.out.println(requestBuilder.toString());

        SearchResponse response = requestBuilder.get();
        Suggest suggest = response.getSuggest();//suggest实体

        Set<String> suggestSet = new HashSet<>();//set
        int maxSuggest = 0;
        if (suggest != null) {
            Suggest.Suggestion result = suggest.getSuggestion("student_suggest");//获取suggest,name任意string
            for (Object term : result.getEntries()) {
                if (term instanceof CompletionSuggestion.Entry) {
                    CompletionSuggestion.Entry item = (CompletionSuggestion.Entry) term;
                    if (!item.getOptions().isEmpty()) {
                        //若item的option不为空,循环遍历
                        for (CompletionSuggestion.Entry.Option option : item.getOptions()) {
                            String tip = option.getText().toString();
                            /*float sco = option.getScore();
                            System.out.println(tip+"---"+sco);*/
                            if (!suggestSet.contains(tip)) {
                                suggestSet.add(tip);
                                ++maxSuggest;
                            }
                        }
                    }
                }
                if (maxSuggest >= suggestMaxCount) {
                    break;
                }
            }
        }

        List<String> suggests = Arrays.asList(suggestSet.toArray(new String[]{}));

        suggests.forEach((s)->{
            System.out.println(s);
        });

		/*return	 suggests;*/

    }

 

kibana语句如下:

GET /news_website/news/_search
{
  "suggest": {
    "my-suggest" : {
      "prefix" : "西游",
      "completion" : {
        "field" : "title.suggest",
        "size":10   ##显示前10条
      }
    }
  }
}

 

第二种方式:基于Match Phrase Prefix Query

java代码如下:

public List<EsModel> prefixQuery(String name, String text){
		// 构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        QueryBuilder basicQuery = boolQueryBuilder.must(QueryBuilders.matchPhrasePrefixQuery(name, text).maxExpansions(5));
        queryBuilder.withQuery(basicQuery);
        List<EsModel> list = template.queryForList(queryBuilder.build(), EsModel.class);
        return list;
		
	}

@RequestMapping("prefixQuery")
	public List<EsModel> prefixQuery(){
		List<EsModel> list = esUtils.prefixQuery("title", "西游");
		return list;
		
	}

 kibana语句如下:

GET /news_website/news/_search
{
  "query": {
    "match_phrase_prefix": {
      "title": {
        "query": "西游"
      }
    }
  },
  "size":10 ##分页 一页显示10条
}

 

对比:

注意:第一种方式我使用的字段是title.suggest,原因是 设置了title.suggest字段为completion类型,因此使用了suggest的方式实现搜索提示;第二种方式我使用的字段是title,而title是text类型,所以直接使用elastic的原生查询检索到了结果,但是这样的结果有一部分是我们需要的,会检索出来一些垃圾数据,因此不推荐;同时在对比当中我们也看到了,如果第二种方式的字段我们也使用title.suggest,也达到了预期的结果;究竟用这两种方式哪一种好一点,目前我也不大清楚,有知道的大神欢迎提出了。

索引库创建参考:https://blog.csdn.net/wuzhiwei549/article/details/80530992

java程序代码参考:https://blog.csdn.net/wangxudongx/article/details/87275232

Match Phrase Query 和 Match Phrase Prefix Query比较:https://www.cnblogs.com/reycg-blog/p/10012238.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值