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

 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

es的自动补全查询——DSL语句&java代码实现_第1张图片

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

es的自动补全查询——DSL语句&java代码实现_第2张图片

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

es的自动补全查询——DSL语句&java代码实现_第3张图片

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

service层:

List getSuggestions(String prefix);

serviceimpl层:

@Override
public List getSuggestions(String prefix) {
    try {
        // 1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        // 2.准备DSL
        request.source().suggest(new SuggestBuilder().addSuggestion(
            "suggestions",// 查询的名称,自定义
            SuggestBuilders.completionSuggestion("suggestion")//自动补全的字段名
            .prefix("北京")//关键字,查询以北京开头的数据
            .skipDuplicates(true)// 跳过重复词条
            .size(10)//显示的词条数量
        ));
        // 3.发起请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析结果
        Suggest suggest = response.getSuggest();
        // 4.1.根据补全查询名称,获取补全结果
        CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");
        // 4.2.获取options
        List options = suggestions.getOptions();
        // 4.3.遍历
        List list = new ArrayList<>(options.size());
        for (CompletionSuggestion.Entry.Option option : options) {
            String text = option.getText().toString();
            list.add(text);
        }
        return list;
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

你可能感兴趣的:(es,微服务,elasticsearch,大数据)