ElasticSearch 连载二 中文分词

上一章ElasticSearch 连载一 基础入门 对Elastic的概念、安装以及基础操作进行了介绍。

那是不是有童鞋会有以下几个问题呢?

  1. 什么是中文分词器?

  2. 分词器怎么安装?

  3. 如何使用中文分词器?

那么接下来就为大家细细道来。

什么是中文分词器

搜索引擎的核心是 倒排索引 而倒排索引的基础就是分词。所谓分词可以简单理解为将一个完整的句子切割为一个个单词的过程。在 es 中单词对应英文为 term。我们简单看下面例子:

我爱北京天安门

ES 的倒排索引即是根据分词后的单词创建,即 北京天安门这4个单词。这也意味着你在搜索的时候也只能搜索这4个单词才能命中该文档。

分词器安装

首先,安装中文分词插件。这里使用的是 ik

./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v5.5.1/elasticsearch-analysis-ik-5.5.1.zip

上面代码安装的是5.5.1版的插件,与 Elastic 5.5.1 配合使用。

安装结束后,会发现目录 /elasticsearch-5.5.1/plugins 多了一个analysis-ik 的文件。

接着,重新启动 Elastic ,就会自动加载这个新安装的插件。

最简单的测试

用下面命令测试一下ik分词器:

curl -X GET 'http://localhost:9200/_analyze?pretty&analyzer=ik_smart' -d '我爱北京天安门'

返回结果:

{
"tokens" : [
{
"token" : "我",
"start_offset" : ,
"end_offset" : ,
"type" : "CN_CHAR",
"position" :
},
{
"token" : "爱",
"start_offset" : ,
"end_offset" : ,
"type" : "CN_CHAR",
"position" :
},
{
"token" : "北京",
"start_offset" : ,
"end_offset" : ,
"type" : "CN_WORD",
"position" :
},
{
"token" : "天安门",
"start_offset" : ,
"end_offset" : ,
"type" : "CN_WORD",
"position" :
}
]
}

那么恭喜你,完成了ik分词器的安装。

如何使用中文分词器

概念

这里介绍下 什么是_all字段, 其实all字段是为了在不知道搜索哪个字段时,使用的。ES会把所有的字段(除非你手动设置成false),都放在all中,然后通过分词器去解析。当你使用query_string的时候,默认就在这个_all字段上去做查询,而不需要挨个字段遍历,节省了时间。

properties中定义了特定字段的分析方式

  • type,字段的类型为string,只有string类型才涉及到分词,像是数字之类的是不需要分词的。

  • store,定义字段的存储方式,no代表不单独存储,查询的时候会从_source中解析。当你频繁的针对某个字段查询时,可以考虑设置成true。

  • term_vector,定义了词的存储方式,with_position_offsets,意思是存储词语的偏移位置,在结果高亮的时候有用。

  • analyzer,定义了索引时的分词方法

  • search_analyzer,定义了搜索时的分词方法

  • include_in_all,定义了是否包含在_all字段中

  • boost,是跟计算分值相关的。

添加Index

然后,新建一个 Index,指定需要分词的字段。这一步根据数据结构而异,下面的命令只针对本文。基本上,凡是需要搜索的中文字段,都要单独设置一下。

curl -X PUT 'localhost:9200/school' -d '
{
"mappings": {
"student": {
"_all": {
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word",
"term_vector": "no",
"store": "false"
},
"properties": {
"user": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word",
"include_in_all": "true",
"boost":
},
"desc": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word",
"include_in_all": "true",
"boost":
}
}
}
}
}'

上面代码中,首先新建一个名称为school的 Index,里面有一个名称为student的 Type。student有三个字段。

  • user

  • desc

这两个字段都是中文,而且类型都是文本(text),所以需要指定中文分词器,不能使用默认的英文分词器。

上面代码中,analyzer是字段文本的分词器,search_analyzer是搜索词的分词器。ik_max_word分词器是插件ik提供的,可以对文本进行最大数量的分词。

数据操作

创建好了Index后,我们来实际演示下:

新增记录

curl -X PUT 'localhost:9200/school/student/1' -d '
{
"user": "许星星",
"desc": "这是一个不可描述的姓名"
}'
curl -X PUT 'localhost:9200/school/student/2' -d '
{
"user": "天上的星星",
"desc": "一闪一闪亮晶晶,爸比会跳舞"
}'
curl -X PUT 'localhost:9200/school/student/3' -d '
{
"user": "比克大魔王",
"desc": "拿着水晶棒,亮晶晶的棒棒。"
}'

返回数据:

{
"_index": "school",
"_type": "student",
"_id": "",
"_version": ,
"result": "updated",
"_shards": {
"total": ,
"successful": ,
"failed":
},
"created": false
}

全文搜索

Elastic 的查询非常特别,使用自己的查询语法,要求 GET 请求带有数据体。

curl 'localhost:9200/school/student/_search'  -d '
{
"query" : { "match" : { "desc" : "晶晶" }}
}'

上面代码使用 Match 查询,指定的匹配条件是desc字段里面包含"晶晶"这个词。返回结果如下。

{
"took": ,
"timed_out": false,
"_shards": {
"total": ,
"successful": ,
"failed":
},
"hits": {
"total": ,
"max_score": 2.5811603,
"hits": [
{
"_index": "school",
"_type": "student",
"_id": "",
"_score": 2.5811603,
"_source": {
"user": "比克大魔王",
"desc": "拿着水晶棒,亮晶晶的棒棒。"
}
},
{
"_index": "school",
"_type": "student",
"_id": "",
"_score": 2.5316024,
"_source": {
"user": "天上的星星",
"desc": "一闪一闪亮晶晶,爸比会跳舞"
}
}
]
}
}

Elastic 默认一次返回10条结果,可以通过size字段改变这个设置。

curl 'localhost:9200/school/student/_search'  -d '
{
"query" : { "match" : { "desc" : "晶晶" }},
"size" :
}'

上面代码指定,每次只返回一条结果。

还可以通过from字段,指定位移

curl 'localhost:9200/school/student/_search'  -d '
{
"query" : { "match" : { "desc" : "晶晶" }},
"size" : ,
"from" :
}'

上面代码指定,从位置1开始(默认是从位置0开始),只返回一条结果。

逻辑运算

如果有多个搜索关键字, Elastic 认为它们是or关系。

curl 'localhost:9200/school/student/_search'  -d '
{
"query" : { "match" : { "desc" : "水晶棒 这是" }}
}'

返回结果:

{
"took": ,
"timed_out": false,
"_shards": {
"total": ,
"successful": ,
"failed":
},
"hits": {
"total": ,
"max_score": 5.1623206,
"hits": [
{
"_index": "school",
"_type": "student",
"_id": "",
"_score": 5.1623206,
"_source": {
"user": "比克大魔王",
"desc": "拿着水晶棒,亮晶晶的棒棒。"
}
},
{
"_index": "school",
"_type": "student",
"_id": "",
"_score": 2.5811603,
"_source": {
"user": "许星星",
"desc": "这是一个不可描述的姓名"
}
}
]
}
}

如果要执行多个关键词的and搜索,必须使用布尔查询

curl 'localhost:9200/school/student/_search'  -d '
{
"query": {
"bool": {
"must": [
{ "match": { "desc": "水晶棒" } },
{ "match": { "desc": "亮晶晶" } }
]
}
}
}'

返回结果:

{
"took": ,
"timed_out": false,
"_shards": {
"total": ,
"successful": ,
"failed":
},
"hits": {
"total": ,
"max_score": 10.324641,
"hits": [
{
"_index": "school",
"_type": "student",
"_id": "",
"_score": 10.324641,
"_source": {
"user": "比克大魔王",
"desc": "拿着水晶棒,亮晶晶的棒棒。"
}
}
]
}
}

总结

本章介绍了分词器的基本概念和使用,至此Elastic算是有一个基本的入门,下一章节将进一步学习分词器的特性以及场景案例。

原文地址

https://github.com/WilburXu/blog/blob/master/ElasticSearch/ElasticSearch%20%E8%BF%9E%E8%BD%BD%E4%BA%8C%20%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D.md

ElasticSearch 连载二 中文分词的更多相关文章

  1. elasticsearch使用ik中文分词器

    elasticsearch使用ik中文分词器 一.背景 二.安装 ik 分词器 1.从 github 上找到和本次 es 版本匹配上的 分词器 2.使用 es 自带的插件管理 elasticsearc ...

  2. Elasticsearch安装ik中文分词插件(四)

    一.IK简介 IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包.从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本.最初,它是以开源项目Lu ...

  3. 如何在Elasticsearch中安装中文分词器(IK)和拼音分词器?

    声明:我使用的Elasticsearch的版本是5.4.0,安装分词器前请先安装maven 一:安装maven https://github.com/apache/maven 说明: 安装maven需 ...

  4. Elasticsearch:hanlp 中文分词器

    HanLP 中文分词器是一个开源的分词器,是专为Elasticsearch而设计的.它是基于HanLP,并提供了HanLP中大部分的分词方式.它的源码位于: https://github.com/Ke ...

  5. Elasticsearch系列---使用中文分词器

    前言 前面的案例使用standard.english分词器,是英文原生的分词器,对中文分词支持不太好.中文作为全球最优美.最复杂的语言,目前中文分词器较多,ik-analyzer.结巴中文分词.THU ...

  6. elasticsearch之集成中文分词器

    IK是基于字典的一款轻量级的中文分词工具包,可以通过elasticsearch的插件机制集成: 一.集成步骤 1.在elasticsearch的安装目录下的plugin下新建ik目录: 2.在gith ...

  7. Elasticsearch:IK中文分词器

    Elasticsearch内置的分词器对中文不友好,只会一个字一个字的分,无法形成词语,比如: POST /_analyze { "text": "我爱北京天安门&quo ...

  8. 如何在Elasticsearch中安装中文分词器(IK+pinyin)

    如果直接使用Elasticsearch的朋友在处理中文内容的搜索时,肯定会遇到很尴尬的问题--中文词语被分成了一个一个的汉字,当用Kibana作图的时候,按照term来分组,结果一个汉字被分成了一组. ...

  9. Elasticsearch如何安装中文分词插件ik

    elasticsearch-analysis-ik 是一款中文的分词插件,支持自定义词库. 安装步骤: 1.到github网站下载源代码,网站地址为:https://github.com/medcl/ ...

随机推荐

  1. HTML布局水平导航条1制作

    该文是用css制作个导航条,用竖线分隔,导航条是点击的多个区块.步骤:ul里设置需要数量的li,li中加上a链接给ul加样式,去掉默认的前面的点给li设置左浮动,让ul里的li横向排列a链接设置成块状 ...

  2. DevOps - DevOps精要 - 歧途

    前言 如果在实施DevOps的过程中,周围没有一个人支持你,也没有得到领导和团队成员的理解: 如果在采用DevOps的工具和方法之后,难以获得明显的效率提升,甚至得到了不少的消极反馈: 那就需要反省一 ...

  3. setInterval【计时器】

    ~function(){ const nextPushTime = $('#nextPushTime_promotion_push'); const prevTime = new Date('2017 ...

  4. Appium移动自动化测试-----(六)1.appium-desktop下载安装

    Appium 移动测试中有个很重新的组件 Appium-Server,它主要用来监听我们的移动设备(真机或模拟器),然将不同编程语言编写的 appium 测试脚本进行解析,然后,驱动移动设备来运行测试 ...

  5. Spring中声明式事务的注解@Transactional的参数的总结(REQUIRED和REQUIRES_NEW的与主方法的回滚问题)

    一.事务的传播行为1.介绍 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播.例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行.2.属性 事务的传播行为可以由传 ...

  6. 如何使用C++实现单链表

    线性表--链表 为什么假期也在发文章 //TODO NullGirlfrindException 请忽略以上两行无聊的事实...... 如何弥补顺序表的不足之处? 第一次学习线性表一定会马上接触到一种 ...

  7. [转帖]C语言计算时间函数 & 理解linux time命令的输出中“real”“user”“sys”的真正含义

    C语言计算时间函数 & 理解linux time命令的输出中“real”“user”“sys”的真正含义 https://blog.csdn.net/willyang519/article/d ...

  8. 【转帖】2019年中国5G行业细分市场发展现状和市场前景分析 通信基站数量快速增长

    2019年中国5G行业细分市场发展现状和市场前景分析 通信基站数量快速增长 中国有 600多万个基站 平均每200个人 一个基站.. 一个基站十万块钱的话 相当于 每个人 需要分摊 500块钱. ht ...

  9. k8s 证书反解

    k8s证书反解 1.将k8s配置文件(kubelet.kubeconfig)中client-certificate-data:内容拷贝 2.echo "client-certificate- ...

  10. oracle 生成随机日期+时间

    oracle 生成随机日期+时间 SELECT to_date(TRUNC(DBMS_RANDOM.VALUE(to_number(to_char(to_date('20110101','yyyymm ...