elasticsearchES

Elasticsearch-自动补全

2022-04-05  本文已影响0人  石头耳东

零、本文纲要

tips:Ctrl + F快速定位所需内容进行阅读吧。

一、自动补全

当用户在搜索框输入字符时,提示出与该字符有关的搜索项,如图:

自动补全.png

二、使用拼音分词

开源的拼音分词插件:Pinyin Analysis plugin

查看elasticsearch的plugins目录位置,命令如下:

docker volume inspect es-plugins

显示结果:

[
    {
        "CreatedAt": "2022-04-04T17:07:34+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/es-plugins/_data",
        "Name": "es-plugins",
        "Options": null,
        "Scope": "local"
    }
]
plugins目录位置.png
docker restart es

三、自定义分词器

1、分词器的组成

分词器的组成.png

2、使用自定义分词器

如果直接使用分词器创建索引库,会创建大量的单字拼音索引,浪费空间,如下:

直接使用的情形.png

使用pinyin分词器创建倒排索引,会导致shizi下同时存在狮子和虱子;此时,我们去搜素时,分词器又会分词出shizi,得到虱子的数据,不符合预期,如下:

同时使用自定义分词器创建倒排索引和搜索.png 不和预期产生原因.png
# 自定义分词器
PUT /test 
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": { //自定义分词器
          "tokenizer": "ik_max_word", //先ik
          "filter": "py" //后py
        }
      },
      "filter": { //配置pinyin分词器
        "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": {
      "name": {
        "type": "text",
        "analyzer": "my_analyzer",
        "search_analyzer": "ik_smart"
      }
    }
  }
}

四、ES自动补全

官方文档:ES completion suggester

1、completion suggester查询

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

2、使用DSL语句进行查询

使用DSL语句进行查询.png

实例:

# 自动补全索引库
PUT /test2
{
  "mappings": {
    "properties": {
      "title": {
        "type": "completion"
      }
    }
  }
}

POST /test2/_doc
{
  "title": ["Sony", "WH-1000XM4"]
}
POST /test2/_doc
{
  "title": ["SK-II", "PITERA"]
}
POST /test2/_doc
{
  "title": ["Nintendo", "switch"]
}

GET /test2/_search
{
  "suggest": {
    "titleSuggest": {
      "text": "s", //查询的关键字
      "completion": {
        "field": "title", //补全查询的字段
        "skip_duplicates": true, //跳过重复数据
        "size": 10 //获取前10条结果
      }
    }
  }
}

3、RestClient实现自动补全

// 1. 获取请求对象
SearchRequest request = new SearchRequest("hotel");

// 2. 准备DSL语句
request.source().suggest(new SuggestBuilder().addSuggestion(
        "hotelSuggest",
        SuggestBuilders.completionSuggestion("suggestion")
                .prefix("sh")
                .skipDuplicates(true)
                .size(10)
));

// 3. 发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
准备DSL查询.png
// 4. 解析响应
Suggest suggest = response.getSuggest();
// 4.1 根据补全查询名称,获取补全结果
CompletionSuggestion suggestions = suggest.getSuggestion("hotelSuggest");
// 4.2 获取options
List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
// 4.3 遍历
for (CompletionSuggestion.Entry.Option option : options) {
    String text = option.getText().toString();

    // 5. 输出结果
    System.out.println(text);
}
解析结果数据.png

五、结尾

以上即为自动补全的全部内容,感谢阅读。

上一篇 下一篇

猜你喜欢

热点阅读