本文来看一下ES的多字段特性,以及如何配置一个自定义的分词器。

一、多字段类型

多字段特性:可以实现精确匹配。可以使用不同的analyzer,就是搜索的时候是一个分词器,插入的时候是另一个分词器。

1、Exact Values && Full Text

精确值和全文检索值。精确值的意思就是不分词,不全文检索。当成mysql中的那种等值查询。全文文本值意思就是查询的时候走的是分词的路子,全文文本的匹配。

1.1、Exact Values

包括数字类型,日期类型,具体字符串类型(keyword类型),这几个类型在ES中是不分词的。
因为精确值不需要做分词的处理,所以ES为每一个精确值类型做索引的时候,不分词处理,就是简单的存进去一个倒排索引。不分词,存的是完整的词。

1.2、Full Text

ES中的text类型走的就是Full Text的路子,是分词检索和索引的。

二、自定义分词器

当ES自带的分词器无法满足的时候,可以自定义分词器,通过自己组合不同的组件来实现不同的分词效果。
我们前面讲分词器的时候说过,ES中分词效果的实现是由三个组件实现的。分别是:

Character Filters
它是在Tokenizer之前对文本进行处理,例如增加删除以及替换文本字符,可以配置多个Character Filters 串行做处理,因为他处理了文本的内容,所以会影响Tokenizer的position和offset信息。
ES中内置了一些Character Filters分别是:
HTML strip:去除html标签
Mapping:字符串替换
Pattern replace:正则匹配替换
Tokenizer:
他的作用是讲原始的文本按照一定的规则,切分为分词,
ES内置的Tokenizer有:whitespace/standard/uax_url_email/pattern/keyword/path hierarchy 其中keyword不做任何处理,就是一个原样的。
也可以自己使用java开发插件,实现自己的Tokenizer。
Token Filter:
是将Tokenizer输出的单词(term)进行增加,修改,删除。
做一些后续处理,ES内置的Token Filter有
Lowercase /stop/synonym 分别是把大写字母转小写,增加停用词,增加近义词。
基于ES提供的这些内置组件,我们就可以在开发的时候自己定义自己的分析器实现对应你想要的效果。

下面我们就针对这些概念,自己实现一个自己想要的分词器。

1、去除html标签的分词组合

# 自己组装一个去除html标签的分词器效果
POST _analyze
{"tokenizer": "keyword","char_filter": ["html_strip"],"text": "<b>hello es</b>"
}
注意我们这里就是看看测试效果,具体真的定义分词器不是在这里。类似做个单元测试。
keyword表示我们这个词hello es在索引的时候不做分词,插进去原样,取出来原样。
结果就是去掉了html标签。
{"tokens" : [{"token" : "hello es",  去掉了html标签"start_offset" : 3,"end_offset" : 15,"type" : "word","position" : 0}]
}

当我们做一些爬虫数据的时候,爬下来的数据可以做一个html标签的剥离。

2、使用char filter进行替换

#使用char filter进行替换
POST _analyze
{"tokenizer": "standard","char_filter": [{"type" : "mapping","mappings" : [ "- => _"]}],"text": "123-456, I-test! test-990 650-555-1234"
}
这个分词我们使用的是标准分词,char_filter我们用的是mapping类型,其中的映射关系指定为把中划线转为下划线。注意对文本还是会分词的,标准的就是按照字母一个一个词分出来的。
{"tokens" : [{"token" : "123_456","start_offset" : 0,"end_offset" : 7,"type" : "<NUM>","position" : 0},{"token" : "I_test","start_offset" : 9,"end_offset" : 15,"type" : "<ALPHANUM>","position" : 1},{"token" : "test_990","start_offset" : 17,"end_offset" : 25,"type" : "<ALPHANUM>","position" : 2},{"token" : "650_555_1234","start_offset" : 26,"end_offset" : 38,"type" : "<NUM>","position" : 3}]
}
我们看到他把所有的中划线,转为了下划线,并且进行了分词。而且感叹号也被去掉了。

还可以把一些表情转为字符,我们把笑脸转为happy 把哭脸转为sad

//char filter 替换表情符号
POST _analyze
{"tokenizer": "standard","char_filter": [{"type" : "mapping","mappings" : [ ":) => happy", ":( => sad"]}],"text": ["I am felling :)", "Feeling :( today"]
}

3、正则表达式

#正则表达式
GET _analyze
{"tokenizer": "standard","char_filter": [{"type" : "pattern_replace",   "pattern" : "http://(.*)","replacement" : "$1"}],"text" : "http://www.elastic.co"
}
效果就是replace掉了http那块的正则表达式。
{"tokens" : [{"token" : "www.elastic.co","start_offset" : 0,"end_offset" : 21,"type" : "<ALPHANUM>","position" : 0}]
}

4、指定分词组件tokenizer

4.1、按文件路径切分词汇

POST _analyze
{"tokenizer":"path_hierarchy","text":"/user/ymruan/a/b/c/d/e"
}
这个分词组件会把你的路径按照级别全部拆分出来,你能查到所有的路径和子路径"tokens" : [{"token" : "/user","start_offset" : 0,"end_offset" : 5,"type" : "word","position" : 0},{"token" : "/user/ymruan","start_offset" : 0,"end_offset" : 12,"type" : "word","position" : 0},{"token" : "/user/ymruan/a","start_offset" : 0,"end_offset" : 14,"type" : "word","position" : 0},{"token" : "/user/ymruan/a/b","start_offset" : 0,"end_offset" : 16,"type" : "word","position" : 0},{"token" : "/user/ymruan/a/b/c","start_offset" : 0,"end_offset" : 18,"type" : "word","position" : 0},{"token" : "/user/ymruan/a/b/c/d","start_offset" : 0,"end_offset" : 20,"type" : "word","position" : 0},{"token" : "/user/ymruan/a/b/c/d/e","start_offset" : 0,"end_offset" : 22,"type" : "word","position" : 0}]
}

5、定义filter

1、停用词的操作

# whitespace与stop
POST _analyze
{"tokenizer": "whitespace","filter": ["stop"],"text": ["The rain in Spain falls mainly on the plain."]
}
我们的分词是按空格分的,同时指定了过滤掉一些停用词,前面说过诸如像介词之类的,a an the什么的。但是注意,the会被过滤,但是一旦有了大写字符就不会被过率了,所以第一个The是不会被过滤掉的。
{"tokens" : [{"token" : "The","start_offset" : 0,"end_offset" : 3,"type" : "word","position" : 0},{"token" : "rain","start_offset" : 4,"end_offset" : 8,"type" : "word","position" : 1},{"token" : "Spain","start_offset" : 12,"end_offset" : 17,"type" : "word","position" : 3},{"token" : "falls","start_offset" : 18,"end_offset" : 23,"type" : "word","position" : 4},{"token" : "mainly","start_offset" : 24,"end_offset" : 30,"type" : "word","position" : 5},{"token" : "plain.","start_offset" : 38,"end_offset" : 44,"type" : "word","position" : 8}]
}
我们看到那些介词都没了,但是大写的Theh还在。其余的也是同理。

但是我们可以这样去掉The

#/remove 加入lowercase后,The被当成 stopword删除
POST _analyze
{"tokenizer": "whitespace","filter": ["lowercase","stop"],"text": ["The gilrs in China are playing this game!"]
}
因为我们说filter是可以多个的,所以你在stop之前加一个转小写,The被转为the就能去掉了"tokens" : [{"token" : "gilrs","start_offset" : 4,"end_offset" : 9,"type" : "word","position" : 1},{"token" : "china","start_offset" : 13,"end_offset" : 18,"type" : "word","position" : 3},{"token" : "playing","start_offset" : 23,"end_offset" : 30,"type" : "word","position" : 5},{"token" : "game!","start_offset" : 36,"end_offset" : 41,"type" : "word","position" : 7}]
}
注意一定要在前面转小写,你放到stop后面他先看停用发现你是大写The就被保留了,然后走转小写的过滤,最后就是the被保留了。

6、自己实现真的分词器

前面都是测试效果用的,现在就真的开始搞一个分词器给索引用。

#自定义分词器
PUT myindex    自己定义一个索引
{"settings": {      # 在setting里面配置分词配置"analysis": {"analyzer": {"my_div_analyzer":{   # 分词器的名字叫my_div_analyzer"type":"custom",  # 类型是自定义的"char_filter":["emoticons"],  # 过滤器是emoticons,下面自定义的"tokenizer": "punctuation",   # 分词组件是punctuation,下面自定义的"filter":[                    # 过滤器是大写转小写的,还有english_stop,这个english_stop是自己下面定义的"lowercase","english_stop"]}},"tokenizer": {"punctuation":{  # 自己定义的,名字自取。类型就是正则匹配,正则表达式自己写就行,按照逗号分词"type":"pattern","pattern":"[.,!?]"}},"char_filter": {"emoticons":{ # 自己定义的,名字自取,类型是mapping的,笑脸转为happy,哭脸是sad"type" : "mapping","mappings" : [":) => _happy_",":( => _sad_"]}},"filter": {"english_stop":{ # 自己定义的,名字自取,类型就是stop,禁用词类型是_english_,前面有说是默认的"type":"stop","stopwords":"_english_"}}}}
}

测试一下:

POST myindex/_analyze
{"analyzer": "my_div_analyzer","text": "I  am a :) person,and you?"
}
分词结果是:
{"tokens" : [{"token" : "i  am a _happy_ person","start_offset" : 0,"end_offset" : 17,"type" : "word","position" : 0},{"token" : "and you","start_offset" : 18,"end_offset" : 25,"type" : "word","position" : 1}]
}
我们看到大写被转了小写,笑脸被转了happy,而且分词分开的也是按逗号分开的,这就是我们定义分词器的效果。

三、总结

我们既然知道了分词器的三个组成部件,也知道了它能随意组合,是一个类似插拔式的操作。所以我们就能根据ES内置的一些基础的组件随意组合。当然了进阶的你也可以自己以JAVA语言定义组件然后拿来组合。

橘子学ES16之分词三大组件以及如何自己实现自己的分词器相关推荐

  1. 橘子学ES09之分词以及各大分词器

    在ES中有很重要的一个概念就是分词,ES的全文检索也是基于分词结合倒排索引做的.所以这一文我们来看下何谓之分词.如何分词. 一.Analysis和Analyzer Analysis和Analyzer是 ...

  2. 橘子学ES19之词项搜索全文检索

    在ES中,词项搜索也叫term搜索,term就有词项的意思.词项检索的意思就是说我输入一个词汇,在检索的时候不会把你输入的这个词汇做分词,匹配条件就是完整的输入的词汇,但是文档插入的时候该分词还是分词 ...

  3. 2021年大数据Hadoop(二十六):YARN三大组件介绍

    全网最详细的Hadoop文章系列,强烈建议收藏加关注! 后面更新文章都会列出历史文章目录,帮助大家回顾知识重点. 目录 本系列历史文章 前言 Yarn三大组件介绍 ResourceManager No ...

  4. java web三大组件之filter过滤器

    过滤器是java web中相当重要的组成成分,是JavaWeb三大组件之一,它与Servlet很相似.不过过滤器有以下三条特性: 过滤器是用来拦截请求的,而不是处理请求的. 当用户请求某个Servle ...

  5. 三大组件与三大优势 SUSE发布CaaS平台为哪般?

    在当下,容器技术的热度不亚于夏日的骄阳.容器技术正在创新应用程序的开发和运行方式,然而各大企业并不想自己安装和维护设置复杂.安全性要求又高的容器基础架构,而是把精力集中在那些可为其业务带来价值的应用程 ...

  6. 第一章 java nio三大组件与使用姿势

    本案例来源于<netty权威指南> 一.三大组件 Selector:多路复用器.轮询注册在其上的Channel,当发现某个或者多个Channel处于"就绪状态"后(ac ...

  7. JavaWeb三大组件(Servlet,Filter,Listener 自己整理,初学者可以借鉴一下)

    JavaWeb三大组件(Servlet,Filter,Listener 自己整理,初学者可以借鉴一下) Reference 转载于:https://www.cnblogs.com/Jeremy2001 ...

  8. 【Netty】NIO 简介 ( NIO 模型 | NIO 三大组件 | 选择器 Selector | 通道 Channel | 缓冲区 Buffer | NIO 组件分配 | 缓冲区示例 )

    文章目录 I . NIO 模型 II . NIO 三大组件交互流程 III . NIO 缓冲区 IV . NIO 与 BIO 对比 V . NIO 线程分配 VI . 缓冲区 ( Buffer ) 示 ...

  9. java怎么监听多个组件,java web(五):java web三大组件之另外两个和八大监听器

    java的三大组件指Servlet.Filter.Listener.八大监听器指八个接口.前面介绍了Servlet,现在介绍一下Filter拦截器以及拦截地址的设置, Listener监听那些事件. ...

最新文章

  1. ios app内嵌入http服务器
  2. pycharm 常用代码签名
  3. 用Advanced Installer制作DotNetBar for Windows Forms 12.0.0.1_冰河之刃重打包版详解
  4. [渝粤题库]西北工业大学复变函数与积分变换
  5. 实例30:python
  6. namespace! 报错
  7. 降级无门!苹果关闭iOS 13.2.2验证通道
  8. Android新建一个activty
  9. Rust 修复隐秘的ReDoS 漏洞
  10. 【f1c200s/f1c100s】RGB接口 LCD驱动适配
  11. 【raft】学习六:etcd/raft 选举和选举优化
  12. 火星来客创业周刊第1期:独立开发者Twitter小工具60天,从月入300美金到月入3000美金
  13. Android 更改鼠标样式
  14. 未来十年的音视频,教科书级别的Android音视频开发教程,学完我成功“挤进”了抖音音视频开发岗
  15. 语义分割yolov5 v4.0 baseline快速复现 快速跑通 图像分割 图像分类 重新训练,训练结果,测试结果,实验图片-20210227
  16. 计院生活--第一章 卧薪尝胆
  17. 3.模板模式_1:什么是模板模式???什么情况适合用模板模式???模板模式如何实现???
  18. C++设计模式——装饰模式(高屋建瓴)
  19. 数字人民币试点范围扩容;美国科技巨头市值蒸发超5万亿美元;蔡崇信再次出售阿里巴巴股票 | 每日大事件...
  20. 软件架构模式-事件驱动

热门文章

  1. 如何下载网站的favicon.ico ,一般都在网站最外层
  2. freertos软件开发和裸机开发区别,freertos程序和裸机程序区别
  3. 干货!深度解读湘钢5G智慧钢铁改造
  4. 什么品牌蓝牙耳机音质好?2022年音质最好的蓝牙耳机推荐
  5. chrome 插件不可用_Chrome 76的新功能,现已可用
  6. csdn论坛中关于在word中生成日历的问题的解答
  7. java值传递址传递
  8. 未经处理的异常: 0xc0000374: 堆已损坏
  9. 游戏安全资讯精选 2018年第二期:游戏行业年度白皮书;手游外挂、直播答题安全风险解析,近30%外挂手游存在致命安全问题,八招应对短信验证码攻击...
  10. 框架 MyBatis使用、Idea 关联 git