es的自动补全查询——DSL语句&java代码实现

21 篇文章 4 订阅

 1、DSL语句

elasticsearch提供了Completion Suggester查询来实现自动补全功能。这个查询会匹配以用户输入内容开头的词条并返回。

为了提高补全查询的效率,对于文档中字段的类型有一些约束:

  • 参与补全查询的字段必须是completion类型。

  • 字段的内容一般是用来补全的多个词条形成的数组。

查询的DSL语句如下:

// 自动补全查询
GET /test/_search
{
  "suggest": {//表示是自动补全查询,固定写法
    "title_suggest": {//给查询起的名字,自定义
      "text": "s", // 关键字,查询s开头的数据
      "completion": {
        "field": "title", // 补全查询的字段,在哪个字段查询
        "skip_duplicates": true, // 跳过重复的
        "size": 10 // 获取前10条结果
      }
    }
  }
}

2、java实现

步骤:

1.确认索引库结构和使用的分词器,建议:创建倒排索引时,使用ik和拼音分词器,查询时使用ik分词器

示例:

// 酒店数据索引库
PUT /hotel
{
  "settings": {
    "analysis": {
      "analyzer": {
        "text_anlyzer": {
          "tokenizer": "ik_max_word",
          "filter": "py"
        },
        "completion_analyzer": {
          "tokenizer": "keyword",
          "filter": "py"
        }
      },
      "filter": {
        "py": {
          "type": "pinyin",
          "keep_full_pinyin": false,
          "keep_joined_full_pinyin": true,
          "keep_original": true,
          "limit_first_letter_length": 16,
          "remove_duplicated_term": true,
          "none_chinese_pinyin_tokenize": false
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "id":{
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "text_anlyzer",
        "search_analyzer": "ik_smart",
        "copy_to": "all"
      },
      "address":{
        "type": "keyword",
        "index": false
      },
      "price":{
        "type": "integer"
      },
      "score":{
        "type": "integer"
      },
      "brand":{
        "type": "keyword",
        "copy_to": "all"
      },
      "city":{
        "type": "keyword"
      },
      "starName":{
        "type": "keyword"
      },
      "business":{
        "type": "keyword",
        "copy_to": "all"
      },
      "location":{
        "type": "geo_point"
      },
      "pic":{
        "type": "keyword",
        "index": false
      },
      "all":{
        "type": "text",
        "analyzer": "text_anlyzer",
        "search_analyzer": "ik_smart"
      },
      "suggestion":{
          "type": "completion",
          "analyzer": "completion_analyzer",
          "search_analyzer": "keyword"
      }
    }
  }
}

2.索引库添加一个新字段suggestion,类型为completion类型

3.在对应的实体类中添加suggestion字段

4.代码实现

自动补全查询的DSL对应的JavaAPI

 自动补全的结果的DSL对应的JavaAPI

 根据前端的请求,完善controller层接口:

@GetMapping("suggestion")
public List<String> getSuggestions(@RequestParam("key") String prefix) {
    return hotelService.getSuggestions(prefix);
}

service层:

List<String> getSuggestions(String prefix);

serviceimpl层:


@Autowired
private RestHighLevelClient client;

 /**
     * 自动补全查询
     * @param prefix
     * @return
     */
    @Override
    public List<String> suggestion(String prefix) {
        try {
            //创建请求
            SearchRequest request = new SearchRequest("hotel");
            //设置参数
            request.source().suggest(
                    new SuggestBuilder().addSuggestion("suggest1", //查询名称(自定义)
                            SuggestBuilders.completionSuggestion("suggestion") //字段名称
                                    .prefix(prefix) //查询prefix开头的词条
                                    .size(10) //相当于mysql的 limit 10
                                    .skipDuplicates(true) //重复词条只保留一份
                    )
            );
            //执行请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            //解析结果
            List<String> list = new ArrayList<>();
            Suggest suggest = response.getSuggest();
            CompletionSuggestion suggest1 = suggest.getSuggestion("suggest1");
            List<CompletionSuggestion.Entry.Option> optionList = suggest1.getOptions();
            for (CompletionSuggestion.Entry.Option option : optionList) {
                String str = option.getText().string();
                list.add(str);
            }

            return list;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值