经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Elasticsearch » 查看文章
elasticsearch实现基于拼音搜索
来源:cnblogs  作者:huan1993  时间:2023/1/16 9:17:34  对本文有异议

1、背景

一般情况下,有些搜索需求是需要根据拼音中文来搜索的,那么在elasticsearch中是如何来实现基于拼音来搜索的呢?可以通过elasticsearch-analysis-pinyin分析器来实现。

2、安装拼音分词器

  1. # 进入 es 的插件目录
  2. cd /usr/local/es/elasticsearch-8.4.3/plugins
  3. # 下载
  4. wget https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v8.4.3/elasticsearch-analysis-pinyin-8.4.3.zip
  5. # 新建目录
  6. mkdir analysis-pinyin
  7. # 解压
  8. mv elasticsearch-analysis-pinyin-8.4.3.zip analysis-pinyin && cd analysis-pinyin && unzip elasticsearch-analysis-pinyin-8.4.3.zip && rm -rvf elasticsearch-analysis-pinyin-8.4.3.zip
  9. cd ../ && chown -R es:es analysis-pinyin
  10. # 启动es
  11. /usr/local/es/elasticsearch-8.4.3/bin/elasticsearch -d

3、拼音分词器提供的功能

拼音分词器提供如下功能
拼音分词器提供的功能
每个选项的含义 可以通过 文档中的例子来看懂。

4、简单测试一下拼音分词器

4.1 dsl

  1. GET _analyze
  2. {
  3. "text": ["我是中国人"],
  4. "analyzer": "pinyin"
  5. }

"analyzer": "pinyin" 此处的pinyin是拼音分词器自带的。

4.2 运行结果

运行结果
从图片上,实现了拼音分词,但是这个不一定满足我们的需求,比如没有中文了,单个的拼音(比如:wo)是没有什么用的,需要对拼音分词器进行定制化。

5、es中分词器的组成

elasticsearch中分词器analyzer由如下三个部分组成:

  1. character filters: 用于在tokenizer之前对文本进行处理。比如:删除字符,替换字符等。
  2. tokenizer: 将文本按照一定的规则分成独立的token。即实现分词功能。
  3. tokenizer filter:tokenizer输出的词条做进一步的处理。比如: 同义词处理,大小写转换、移除停用词,拼音处理等。

处理流程

6、自定义一个分词器实现拼音和中文的搜索

需求: 自定义一个分词器,即可以实现拼音搜索,也可以实现中文搜索。

1、创建mapping

  1. PUT /test_pinyin
  2. {
  3. "settings": {
  4. // 分析阶段的设置
  5. "analysis": {
  6. // 分析器设置
  7. "analyzer": {
  8. // 自定义分析器,在tokenizer阶段使用ik_max_word,在filter上使用py
  9. "custom_analyzer": {
  10. "tokenizer": "ik_max_word",
  11. "filter": "custom_pinyin"
  12. }
  13. },
  14. // 由于不满足pinyin分词器的默认设置,所以我们基于pinyin
  15. // 自定义了一个filter,叫py,其中修改了一些设置
  16. // 这些设置可以在pinyin分词器官网找到
  17. "filter": {
  18. "custom_pinyin": {
  19. "type": "pinyin",
  20. // 不会这样分:刘德华 > [liu, de, hua]
  21. "keep_full_pinyin": false,
  22. // 这样分:刘德华 > [liudehua]
  23. "keep_joined_full_pinyin": true,
  24. // 保留原始token(即中文)
  25. "keep_original": true,
  26. // 设置first_letter结果的最大长度,默认值:16
  27. "limit_first_letter_length": 16,
  28. // 当启用此选项时,将删除重复项以保存索引,例如:de的> de,默认值:false,注意:位置相关查询可能受影响
  29. "remove_duplicated_term": true,
  30. // 如果非汉语字母是拼音,则将其拆分为单独的拼音术语,默认值:true,如:liudehuaalibaba13zhuanghan- > liu,de,hua,a,li,ba,ba,13,zhuang,han,注意:keep_none_chinese和keep_none_chinese_together应首先启用
  31. "none_chinese_pinyin_tokenize": false
  32. }
  33. }
  34. }
  35. },
  36. // 定义mapping
  37. "mappings": {
  38. "properties": {
  39. "name": {
  40. "type": "text",
  41. // 创建倒排索引时使用的分词器
  42. "analyzer": "custom_analyzer",
  43. // 搜索时使用的分词器,搜索时不使用custom_analyzer是为了防止 词语的拼音一样,但是中文含义不一样,导致搜索错误。 比如: 科技 和 客机,拼音一样,但是含义不一样
  44. "search_analyzer": "ik_smart"
  45. }
  46. }
  47. }
  48. }

注意:
可以看到 我们的 name字段 使用的分词器是 custom_analyzer,这个是我们在上一步定义的。但是搜索的时候使用的是 ik_smart,这个为甚么会这样呢?
假设我们存在如下2个文本 科技强国这是一架客机, 那么科技客机的拼音是不是就是一样的。 这个时候如果搜索时使用的分词器也是custom_analyzer那么,搜索科技的时候客机也会搜索出来,这样是不对的。因此在搜索的时候中文就以中文搜,拼音就以拼音搜。

  1. {
  2. "name": {
  3. "type": "text",
  4. "analyzer": "custom_analyzer",
  5. "search_analyzer": "ik_smart"
  6. }
  7. }

analyzersearch_analyzer的值都是custom_analyzer,搜索时也会通过拼音搜索,这样的结果可能就不是我们想要的。

2、插入数据

  1. PUT /test_pinyin/_bulk
  2. {"index":{"_id":1}}
  3. {"name": "科技强国"}
  4. {"index":{"_id":2}}
  5. {"name": "这是一架客机"}
  6. {"index":{"_id":3}}

3、搜索数据

搜索数据

7、参考文档

1、https://github.com/medcl/elasticsearch-analysis-pinyin/tree/master

原文链接:https://www.cnblogs.com/huan1993/p/17053317.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号