ElasticSearch自动补全

一、拼音分词器:

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

这种根据用户输入的字母,提示完整词条的功能,就是自动补全了。

java 复制代码
GET /_analyze
{
  "text":"我爱螺蛳粉",
  "analyzer": "pinyin"
}

这个错误表明 Elasticsearch 在使用全局分析器 pinyin 时遇到了问题,因为它无法找到这个全局分析器。可能是由于缺少配置或插件问题导致的。你需要确保已正确配置了 pinyin 分析器,并且相关的插件已经正确安装和配置:

正确结果会是这样的:

1.1、在线安装拼音分词器:
java 复制代码
# 进入容器内部
docker exec -it es /bin/bash

# 在线下载并安装
./bin/elasticsearch-plugin  install https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v7.12.1/elasticsearch-analysis-pinyin-7.12.1.zip

#退出
exit
#重启容器
docker restart es

说明:安装的链接怎么获得

java 复制代码
[root@db301601 ~]# docker exec -it es bash
[root@877298bbcfdf elasticsearch]# cd /usr/share/elasticsearch/bin
[root@877298bbcfdf bin]# ls
elasticsearch		elasticsearch-cli	elasticsearch-env-from-file  elasticsearch-node		  elasticsearch-setup-passwords  elasticsearch-sql-cli-7.12.1.jar  x-pack-env
elasticsearch-certgen	elasticsearch-croneval	elasticsearch-keystore	     elasticsearch-plugin	  elasticsearch-shard		 elasticsearch-syskeygen	   x-pack-security-env
elasticsearch-certutil	elasticsearch-env	elasticsearch-migrate	     elasticsearch-saml-metadata  elasticsearch-sql-cli		 elasticsearch-users		   x-pack-watcher-env
[root@877298bbcfdf bin]# cd /usr/share/elasticsearch    
[root@877298bbcfdf elasticsearch]# ls
LICENSE.txt  NOTICE.txt  README.asciidoc  bin  config  data  jdk  lib  logs  modules  plugins
[root@877298bbcfdf elasticsearch]# cd /usr/share/elasticsearch/plugins
[root@877298bbcfdf plugins]# ls
analysis-ik




[root@db301601 ~]# docker exec -it es /bin/bash
[root@877298bbcfdf elasticsearch]# ./bin/elasticsearch-plugin  install https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v7.12.1/elasticsearch-analysis-pinyin-7.12.1.zip



[root@877298bbcfdf elasticsearch]# ls
LICENSE.txt  NOTICE.txt  README.asciidoc  bin  config  data  jdk  lib  logs  modules  plugins
[root@877298bbcfdf elasticsearch]# cd plugins
[root@877298bbcfdf plugins]# ls
analysis-ik  analysis-pinyin
  • ./ 是指当前目录的简写。在Linux和类Unix系统中,. 表示当前目录,.. 表示上一级目录。因此,./ 表示当前目录下的文件或目录。在你的命令中,./elasticsearch-plugin 意味着你希望在当前目录中执行名为 elasticsearch-plugin 的可执行文件。
  • 使用正确的命令来删除 Elasticsearch 中的插件。正确的命令是 elasticsearch-plugin remove analysis-ik。这个命令会将名为 analysis-ik 的插件从 Elasticsearch 中移除。
  • elasticsearch-plugin 命令会将插件安装到 Elasticsearch 的插件目录中。通常情况下,插件目录位于 Elasticsearch 安装目录的 plugins 文件夹下。具体位置可能因操作系统和安装方式而异,但通常在 /usr/share/elasticsearch/plugins/opt/elasticsearch/plugins 等位置。
1.2、离线安装拼音分词器:

安装插件需要知道elasticsearch的plugins目录位置,而我们用了数据卷挂载,因此需要查看elasticsearch的数据卷目录,通过下面命令查看数据卷目录:

java 复制代码
docker volume inspect es-plugins
java 复制代码
[root@db301601 ~]# docker restart es
es
[root@db301601 ~]# docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED        STATUS         PORTS                                                                                  NAMES
877298bbcfdf   elasticsearch:7.12.1   "/bin/tini -- /usr/l..."   41 hours ago   Up 2 seconds   0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp   es
881f28a337e6   kibana:7.12.1          "/bin/tini -- /usr/l..."   42 hours ago   Up 42 hours    0.0.0.0:5601->5601/tcp, :::5601->5601/tcp                                              kibana
[root@db301601 ~]#  docker volume ls
DRIVER    VOLUME NAME
local     03b04390f4eefc2da60368f67dbc266b76ccb710fe4275535f77a2067204da11
local     7df7ad63d90a9a6c2e3440b37e261039402950dd96f11677c8936dacd2c03210
local     ece02e3c8db3e86860f63fcc1fe9eb0a7c6f42a2b10d7a6c93d7172017886f40
local     ef6b9cdbe2110ec4802b5941d87d83250d1eb12a547a61ed342a59776fa94184
local     es-data
local     es-logs
local     es-plugins
local     root_data01
local     root_data02
local     root_data03
[root@db301601 ~]# docker volume inspect es-plugins
[
    {
        "CreatedAt": "2024-04-26T16:46:19+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/es-plugins/_data",
        "Name": "es-plugins",
        "Options": null,
        "Scope": "local"
    }
]
[root@db301601 ~]# cd /var/lib/docker/volumes/es-plugins/_data
[root@db301601 _data]# ls
py

说明plugins目录被挂载到了:/var/lib/docker/volumes/es-plugins/_data 这个目录中。

解压缩分词器安装包:把下载好的ik分词器解压缩,重命名为ik:

上传到es容器的插件数据卷中:

重启容器: docker restart es(容器名字)

二、自定义分词器

注意事项:

pinyin分词器默认时有很多缺点,比如每个字都拆分变成拼音,不符合一般需求,并且如果使用pinyin分词器,默认的中文索引就没了,只剩下pinyin索引了。所以,需要完善以下几点:

  • 分词时不仅包含汉字,还需包含拼音
  • 分词时按词分,不是字
  • 使用汉字查询时,不会查询到同音词条目docs

如果只是单独使用拼音分词器,是没办法满足具体业务使用场景的,这时候就需要自定义分词器, 通过自定义分词器,将ik分词器与拼音分词器整合起来,来保证我们的搜索既满足汉字也满足拼音**:**

自定义分词器一定是在创建索引库的时候去设置,它只对你所指定的索引库test有效, settings是索引库配置,我们自定义了三步之中的tokenizerfilter

不完善的错误写法:
java 复制代码
PUT /test
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer":{//自定义分词器名称
         //先分词,分好词后交给filter去处理:
          "tokenizer":"ik_max_word",
          "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": {
      "name":{
        "type": "text",
        "analyzer": "my_analyzer" //用my_analyzer分词器
 
      }
    }
  }
}

​​​​​​​

测试1:这个没问题
java 复制代码
GET /test/_analyze
{
  "text":"我爱螺蛳粉",
  "analyzer": "my_analyzer"
}
 
GET /test/_analyze
{
  "text":"如家酒店还不错",
  "analyzer": "my_analyzer"
}

会生成中文、全拼音、词的缩写

测试2:同音词问题

拼音分词器适合在创建倒排索引的时候使用,但不能在搜索中使用,否则会出现同音词问题

java 复制代码
POST /test/_doc/1
{
  "id":1,
  "name":"狮子"
}

POST /test/_doc/2
{
  "id":2,
  "name":"虱子"
}



GET /test/_search
{
  "query":{
    "match":{
      "name":"掉入狮子笼怎么办"
    }
  }
}

​​​​​​​ ​​​​​​​ ​​​​​​​

为了避免出现同音词问题,拼音分词器适合在创建倒排索引的时候使用,不在搜索中使用

解决方法:

在做mapping映射时,指定两个:analyzer是创建索引时用的,search_analyzer是在搜索时需要的,用户搜的是中文,就拿中文去搜,搜的是英文,才拿英文去搜:

java 复制代码
PUT /test
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer":{
          "tokenizer":"ik_max_word",
          "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": {
      "name":{
        "type": "text",
        "analyzer": "my_analyzer",
        "search_analyzer": "ik_smart"
      }
    }
  }
}

这样才能正确搜出:

java 复制代码
POST /test/_doc/1
{
  "id":1,
  "name":"狮子"
}

POST /test/_doc/2
{
  "id":2,
  "name":"虱子"
}



GET /test/_search
{
  "query":{
    "match":{
      "name":"掉入狮子笼怎么办"
    }
  }
}
总结:

三、自动补全:

刚才我们已经学习了拼音分词器的详细用法,已经能够实现基于拼音去做数据搜索了。接下来我们就来看一下自动补全的基本语法,将来我们就能够实现基于拼音去做自动补全了。

在ES当中自动补全功能是基于completion suggester功能来实现的。这个功能可以在用户输入任意关键字时去索引库中,根据指定字段去匹配,以"用户输入关键字"为前缀的所有词条,并且返回,这就是自动补全 。

自动补全功能对于要查询的字段,会有两个特殊的要求。

  • 第一要求:参与自动补全查询的​​​​​​​字段必须得是completion类型。 咱们以前学习字段的数据类型的时候,我们学过有字符串:text、keyword、数值类型、日期类型,这里又多了一种类型叫completion,它就是专门用来做自动补全查询的;
  • 要求二:**参与自动补全查询的字段值最好得是多个词条形成的数组,这样更有利于将来做自动补全。**尽量把词语分成一个一个的词条放到数组当中 ,这样可以更加人性化。例如要自动补全的字段名叫title,它的字段值可以看到是个数组:耳机的产品信息,它形成了两个词条,而不是一个字符串,为什么他要分开呢?自动补全是根据词条做自动补全的,如果你把它俩合成一个字符串,那将来我们再去做自动补全时,你就只能根据s来补全。那当用户输入w的时候,它无法搜出产品索尼名称。

示例:

DSL语句:
java 复制代码
PUT test2
{
  "mappings":{
    "properties":{
      "title":{
        "type":"completion"
      }
    }
  }
}
java 复制代码
// "title" 字段的数据类型是一个数组(Array)。数组可以包含多个元素,
//这里具体包含了两个字符串,如 "Sony" 和 "WH-1000XM3" 
POST test2/_doc
{
  "title": ["Sony", "WH-1000XM3"]
}
POST test2/_doc
{
  "title": ["SK-II", "PITERA"]
}
POST test2/_doc
{
  "title": ["Nintendo", "switch"]
}
查询语法:

将来我们去做completion suggester查询的时候,查询语法比较特殊: 它这里没有用query,因为不再是搜索了,而是去做自动补全,所以变成了suggest。

java 复制代码
GET /test2/_search
{
  "suggest": {
    "title_suggest": {	//设置这个自动查询操作的名称,名字随便
      "text": "s", // 关键字,用户输入的前缀,s开头的这些词条
      "completion": { //自动补全的类型
        "field": "title", // 自动补全查询的字段名
        "skip_duplicates": true, // 跳过重复的
        "size": 10 // 获取前10条结果
      }
    }
  }
}
java 复制代码
{
  "took" : 16,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "suggest" : {
    "title_suggest" : [
      {
        "text" : "s",
        "offset" : 0,
        "length" : 1,
        "options" : [
          {
            "text" : "SK-II",
            "_index" : "test2",
            "_type" : "_doc",
            "_id" : "_6UOJY8B5is2vprLHEOq",
            "_score" : 1.0,
            "_source" : {
              "title" : [
                "SK-II",
                "PITERA"
              ]
            }
          },
          {
            "text" : "Sony",
            "_index" : "test2",
            "_type" : "_doc",
            "_id" : "_qUOJY8B5is2vprLFUNq",
            "_score" : 1.0,
            "_source" : {
              "title" : [
                "Sony",
                "WH-1000XM3"
              ]
            }
          },
          {
            "text" : "switch",
            "_index" : "test2",
            "_type" : "_doc",
            "_id" : "AKUOJY8B5is2vprLIERe",
            "_score" : 1.0,
            "_source" : {
              "title" : [
                "Nintendo",
                "switch"
              ]
            }
          }
        ]
      }
    ]
  }
}

除了返回text外,还返回了文档的原始信息:

输入so就只查出来一条了:

这就是自动补全功能

相关推荐
TDengine (老段)12 分钟前
TDengine 数学函数 DEGRESS 用户手册
大数据·数据库·sql·物联网·时序数据库·iot·tdengine
TDengine (老段)15 分钟前
TDengine 数学函数 GREATEST 用户手册
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
失散131 小时前
分布式专题——47 ElasticSearch搜索相关性详解
java·分布式·elasticsearch·架构
字节数据平台1 小时前
火山引擎Data Agent再拓新场景,重磅推出用户研究Agent
大数据·人工智能·火山引擎
铭毅天下4 小时前
Elasticsearch 到 Easysearch 数据迁移 5 种方案选型实战总结
大数据·elasticsearch·搜索引擎·全文检索
跨境小新4 小时前
Facebook广告投放:地域定向流量不精准?x个优化指南
大数据·facebook
ZKNOW甄知科技5 小时前
客户案例 | 派克新材x甄知科技,构建全场景智能IT运维体系
大数据·运维·人工智能·科技·低代码·微服务·制造
币须赢6 小时前
688758赛分科技 阴上阴形态 洗盘上涨?
大数据
学掌门6 小时前
大数据知识合集之预处理方法
大数据
Elastic 中国社区官方博客7 小时前
Elasticsearch 推理 API 增加了开放的可定制服务
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索