Elasticsearch 中文搜索时遇到几个问题:

    1. 当搜索关键词如:“人民币”时,如果分词将“人民币”分成“人”,“民”,“币”三个单字,那么搜索该关键词会匹配到很多包含该单字的无关内容,但是如果将该词分词成一个整词“人民币”,搜索单字如“人”字又不会匹配到包含“人民币”关键词的内容,怎么解决这个问题,既保证覆盖度又保证准确度?
    1. 搜索“RMB”时只会匹配到包含“RMB”关键词的内容,实际上,“RMB”和“人民币”是同义词,我们希望用户搜索“RMB”和“人民币”可以相互匹配,ES同义词怎么配置?

接下来从以下几点讲一下怎么ES中文分词

  1. 中文分词器
  2. ES 分词流程之 analysis,analyzer,filter,tokenizer
  3. ES内置分词器
  4. 自定义analyzer
  5. ES同义词功能实现

1.IK 分词器

  • 1,Elasticsearch中文分词我们采用Ik分词,ik有两种分词模式,ik_max_word,和ik_smart模式;

    • ik_max_word 和 ik_smart 什么区别?

ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合;
ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”。

索引时,为了提供索引的覆盖范围,通常会采用ik_max_word分析器,会以最细粒度分词索引,搜索时为了提高搜索准确度,会采用ik_smart分析器,会以粗粒度分词
字段mapping设置如下:

  1. "author": {
  2. "type": "string",
  3. "analyzer": "ik",
  4. "search_analyzer": "ik_smart"
  5. }

2.Elasticsearch之分析(analysis)和分析器(analyzer)

analysis索引分析模块充当analyzer分析器的可配置注册表,通过analyzer对文档索引阶段的字段和搜索String进行处理,自定义analyzer时,通常需要character filter tokenizer token filters来完成

2.1 character filter 字符过滤器

首先字符串经过过滤器(character filter),他们的工作是在分词前处理字符串。字符过滤器能够去除HTML标记,例如把“<a>”变成“a

2.2 tokenizer 分词器

英文分词可以根据空格将单词分开,中文分词比较复杂,可以采用机器学习算法来分词

2.2 token filters 表征过滤器

最后,每个词都通过所有表征过滤(token filters),他可以修改词(例如将“Quick”转为小写),去掉词(例如停用词像“a”、“and”、“the”等等),或者增加词(例如同义词像“a”、“and”、“the”等等)或者增加词(例如同义词像“jump”和“leap”)。

2.3 ES分词流程

character filter-->>tokenizer-->>token filters

2.5 自定义analyzer

官网example:

  1. index :
  2. analysis :
  3. analyzer :
  4. myAnalyzer2 :
  5. type : custom
  6. tokenizer : myTokenizer1
  7. filter : [myTokenFilter1, myTokenFilter2]
  8. char_filter : [my_html]
  9. position_increment_gap: 256
  10. tokenizer :
  11. myTokenizer1 :
  12. type : standard
  13. max_token_length : 900
  14. filter :
  15. myTokenFilter1 :
  16. type : stop
  17. stopwords : [stop1, stop2, stop3, stop4]
  18. myTokenFilter2 :
  19. type : length
  20. min : 0
  21. max : 2000
  22. char_filter :
  23. my_html :
  24. type : html_strip
  25. escaped_tags : [xxx, yyy]
  26. read_ahead : 1024
2.6 分词mapping设置

通常为了保证索引时覆盖度和搜索时准确度,索引分词器采用ik_max_word,搜索分析器采用ik_smart模式

  1. "content": {
  2. "type": "string",
  3. "analyzer": "ik_max_word",
  4. "search_analyzer": "ik_smart"
  5. }
1.7 如果更改了mapping分词器,需要重新索引数据才能生效
  1. POST /_reindex
  2. {
  3. "source": {
  4. "index": "twitter"
  5. },
  6. "dest": {
  7. "index": "new_twitter"
  8. }
  9. }

因为倒排索引中的数据是索引时由分词器来处理的,如果分词器有变化,那么搜索时query关键词即使和doc中关键词相同,但是因为分词器的原因,分出来的词会出现不匹配的情况,因此当mapping或者分词器字典同义词词典等发生变化时,需要reindex索引数据

1.8 更改别名,不重启服务切换索引
  1. POST /_aliases
  2. {
  3. "actions": [
  4. {
  5. "remove": {
  6. "index": "oldindex",
  7. "alias": "alias_oldindex"
  8. }
  9. },
  10. {
  11. "add": {
  12. "index": "newindex",
  13. "alias": "alias_oldindex"
  14. }
  15. }
  16. ]
  17. }

2 同义词

2.1 建议同义词词典

  • elasticsearch /config/analysis 下建议同义词词典文件pro_synonym.txt,采用UTF-8编码,写入内容
  • 同义词内容格式 ,注意标点符号使用英文符号
    • 启航 => 起航 : "=>"左边的词全部会被右边的词替换
    • 启航,起航 :使用","英文逗号分隔,两个词是互等的,分词时会同时分成两个词进行索引或者检索,如"启航"会被分成"启航","起航"两个词分别建立索引或者去倒排索引检索

自定义添加同义词通过ik分词器

  1. "settings": {
  2. "analysis": {
  3. "filter": {
  4. "my_synonym_filter": {
  5. "type": "synonym",
  6. "synonyms_path": "analysis/pro_synonym.txt"
  7. }
  8. },
  9. "analyzer": {
  10. "ik_syno_max_word": {
  11. "tokenizer": "ik",
  12. "filter": "my_synonym_filter"
  13. },
  14. "ik_syno_smart": {
  15. "tokenizer": "ik_smart",
  16. "filter": "my_synonym_filter"
  17. }
  18. }
  19. }
  20. }

想查看同义词效果或者测试分词效果

3 Suggest分词

suggest词需要对拼音前缀,全拼,中文进行前缀匹配,例如:“百度”一词,键入"baidu","bd","百"都必须匹配到,因此在索引的时候需要一词分多个分词器来索引保存,中文采用单字分词,拼音首字母和全拼需要自定义analyzer来索引。

  • Elasticsearch Suggest setting mapping设置参考如下
  1. {
  2. "mappings": {
  3. "suggest": {
  4. "properties": {
  5. "full_pinyin": {
  6. "type": "completion",
  7. "analyzer": "full_pinyin_analyzer",
  8. "payloads": true,
  9. "preserve_separators": false,
  10. "preserve_position_increments": true,
  11. "max_input_length": 50
  12. },
  13. "prefix_pinyin": {
  14. "type": "completion",
  15. "analyzer": "prefix_pinyin_analyzer",
  16. "search_analyzer": "standard",
  17. "payloads": true,
  18. "preserve_separators": false,
  19. "preserve_position_increments": true,
  20. "max_input_length": 50
  21. },
  22. "suggestText": {
  23. "type": "completion",
  24. "analyzer": "standard",
  25. "payloads": true,
  26. "preserve_separators": false,
  27. "preserve_position_increments": true,
  28. "max_input_length": 50
  29. }
  30. }
  31. }
  32. },
  33. "settings": {
  34. "index": {
  35. "analysis": {
  36. "filter": {
  37. "_pattern": {
  38. "type": "pattern_capture",
  39. "preserve_original": "1",
  40. "patterns": ["([0-9])", "([a-z])"]
  41. },
  42. "full_pinyin": {
  43. "keep_first_letter": "false",
  44. "keep_none_chinese_in_first_letter": "false",
  45. "type": "pinyin",
  46. "keep_original": "false",
  47. "keep_full_pinyin": "true"
  48. },
  49. "prefix_pinyin": {
  50. "keep_first_letter": "true",
  51. "none_chinese_pinyin_tokenize": "false",
  52. "type": "pinyin",
  53. "keep_original": "false",
  54. "keep_full_pinyin": "false"
  55. }
  56. },
  57. "analyzer": {
  58. "full_pinyin_analyzer": {
  59. "filter": ["lowercase", "full_pinyin"],
  60. "tokenizer": "standard"
  61. },
  62. "prefix_pinyin_analyzer": {
  63. "filter": ["lowercase", "prefix_pinyin"],
  64. "tokenizer": "standard"
  65. }
  66. }
  67. }
  68. }
  69. }
  70. }

关于搜索关键词会将不相关词搜索出来

  • 解决单字搜索的一种方案

    • 问题:搜索时,搜索牙膏,需检索出包含“牙膏”二字的内容,过滤掉包含“牙”或者“膏”的内容,但是搜索单字“牙”或者“膏”时需要将牙膏匹配出来
    • 方案:加入单字字典,ik_max_word分词时,会把所有形式分出来,因此单字字典,此分词模式下会将单字索引起来,ik_smart会按照最粗粒度分词,搜索关键词时不会匹配单字内容
    • 索引和搜索采用不同分词器 "analyzer": "ik", "search_analyzer": "ik_smart"
    • 过程:更改mapping,searchAnalyzer=ik_smart

[ES]elasticsearch章5 ES的分词(二)的更多相关文章

  1. [ES]elasticsearch章5 ES的分词(一)

    初次接触 Elasticsearch 的同学经常会遇到分词相关的难题,比如如下这些场景: 1.为什么明明有包含搜索关键词的文档,但结果里面就没有相关文档呢? 2.我存进去的文档到底被分成哪些词(ter ...

  2. [ES]elasticsearch章3 ES写入过程解析

    Elasticsearch的写 Elasticsearch采用多Shard方式,通过配置routing规则将数据分成多个数据子集,每个数据子集提供独立的索引和搜索功能.当写入文档的时候,根据routi ...

  3. [ES]elasticsearch章2 ES查询过程解析

    es服务端是准确知道每个document分布在哪个shard上: search一个比较复杂的执行模式,因为我们不知道那些document会被匹配到,任何一个shard上都有可能,所以一个search请 ...

  4. [ES]elasticsearch章4 ES的META们

    在介绍Meta更新流程前,我们先介绍一下ES中Meta的组成.存储方式和恢复方式. 1. Meta:ClusterState.MetaData.IndexMetaData Meta是用来描述数据的数据 ...

  5. [ES]elasticsearch章1 ES各角色的分工

    es集群里的master node.data node和client node到底是怎么个意思,分别有何特点? master节点 主要功能是维护元数据,管理集群各个节点的状态,数据的导入和查询都不会走 ...

  6. Elasticsearch使用系列-ES增删查改基本操作+ik分词

    Elasticsearch使用系列-ES简介和环境搭建 Elasticsearch使用系列-ES增删查改基本操作+ik分词 一.安装可视化工具Kibana ES是一个NoSql数据库应用.和其他数据库 ...

  7. ElasticSearch(简称ES)

    Windows下安装ElasticSearch   ElasticSearch(简称ES)是一个基于Lucene的分布式全文搜索服务器,和SQL Server的全文索引(Fulltext Index) ...

  8. Elasticsearch前沿:ES 5.x改进详解与ES6展望

    转:http://www.dataguru.cn/article-11094-1.html 曾勇(Medcl),Elastic 工程师与布道师,2015 年加入 Elastic 公司.加入 Elast ...

  9. ElasticSearch入门篇Ⅰ --- ES核心知识概括

    C01.什么是Elasticsearch 1.什么是搜索 垂直搜索(站内搜索) 互联网的搜索:电商网站,招聘网站,各种app IT系统的搜索:OA软件,办公自动化软件,会议管理,员工管理,后台管理系 ...

随机推荐

  1. LeetCode 144. Binary Tree Preorder Traversal 二叉树的前序遍历 C++

    Given a binary tree, return the preorder traversal of its nodes' values. Example: Input: [,,] \ / Ou ...

  2. QT 二维图形 原理、发展及应用

    转载自 网易博客:sun的博客 http://zhouyang340.blog.163.com/blog/static/3024095920126710504178/ 2D绘图 Qt4中的2D绘图部分 ...

  3. java mybatis后台判断表是否存在mysql

    <select id="isTableExist" parameterType="string" resultType="int"&g ...

  4. python学习Day12 函数的默认值、三元表达式、函数对象(函数名)的应用场景、名称空间与作用域

    复习 1.字符串的比较: -- 按照从左往右比较每一个字符,通过字符对应的ascii进行比较 2. 函数的参数 : 1)实参与形参:       -- 形参:在函数定义时()中出现的参数       ...

  5. 2、数据结构 proxy 代理 reflect 反射

    增删改查 1.set (数组) 2.map (对象 key value) 数据结构横向对比 map.set('t',1) arr.push({t:1}) set.add({t:1}) arr.push ...

  6. C++ 数组和字符串

    数组和字符串的基本知识 目录 一.数组的声明 二.字符串 一.数组的声明 1.1.存储在每个元素中的值得类型: 1.2.数组名: 1.3.数组中的元素数. ];//short 数组元素值的类型,a数组 ...

  7. vue mock

    如果后端不肯来帮你 mock 数据的话,前端自己来 mock 也是很简单的.你可以使用mock server 或者使用 mockjs + rap 也是很方便的. 不久前出的 easy-mock也相当的 ...

  8. MongoDB集群的搭建

    一.环境准备 1.Centos7 2.mongodb3.4.10 3.三台机器IP分别是:192.168.1.100.192.168.1.135.192.168.1.136 二.mongdb数据库的安 ...

  9. PhoenixFD插件流体模拟——UI布局【Input】详解

    Liquid Input 流体输入 本文主要讲解Input折叠栏中的内容.原文地址:https://docs.chaosgroup.com/display/PHX3MAX/Liquid+Input 主 ...

  10. 桥接模式和nat模式的区别

    桥接模式:VMware虚拟的系统就想局域网中独立的主机一样(有独立的IP)它可以访问网内任何一台机器 Nat模式:可以通过宿主机访问互联网(宿主机联网,虚拟机就能联网)它不能和本局域网中的其他主机进行 ...