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. 代码内存泄露检测(1) MLeaksFinder (Wechat开源) + FBRetainCycleDetector (FaceBook开源)

    每次项目编译完成之后,都被内存搞得头昏脑胀,压力甚大. 利用两周时间,稍微研究了 微信开源的 MLeaksFinder 和 facebook 开源的 FBMemoryProfiler, 这两个开源三方 ...

  2. linux如何找回已经删除的文件?lsof

    简介 lsof(list open files)是一个列出当前系统打开文件的工具.在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以如传输控 ...

  3. 13、OpenCV实现图像的空间滤波——图像平滑

    1.空间滤波基础概念 1.空间滤波基础 空间滤波一词中滤波取自数字信号处理,指接受或拒绝一定的频率成分,但是空间滤波学习内容实际上和通过傅里叶变换实现的频域的滤波是等效的,故而也称为滤波.空间滤波主要 ...

  4. Python标准库: functools (cmp_to_key, lru_cache, total_ordering, partial, partialmethod, reduce, singledispatch, update_wrapper, wraps)

    functools模块处理的对象都是其他的函数,任何可调用对象都可以被视为用于此模块的函数. 1. functools.cmp_to_key(func) 因为Python3不支持比较函数,cmp_to ...

  5. 感受typescript定义变量和数据类型的神奇魔力

    变量和数据类型 你的Javascript能力到达瓶颈?那是因为你还不会typescript.掌握TS,让你的开发更加准确简洁. 今天的学习中,我们接着从TS的数据类型和变量入手,感受它们的奇妙魔力. ...

  6. JWT知识整理

    JSON Web Token:(https://jwt.io/) JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑(Compact)且自包含(Self-co ...

  7. linux环境下编写shell脚本实现启动停止tomcat服务

    第一步:以管理员的身份进入控制台,在指定目录下新建一个shell脚本,我这里命名为tomcat.sh 第二步:编写shell脚本 #!/bin/bash tomcat_home=/usr/tomcat ...

  8. 函数的第一类对象,f格式化,迭代器以及递归

    函数名的第一类对象及使用,f格式化以及迭代器 1.函数的第一类对象 第一类对象 --特殊点 1.可以当作值被赋值给变量 def func(): print(1) a = func a() 2.可以当作 ...

  9. DBA职责和任务

    DBA守则在对生产环境进行修改前,一定要进行备份,一定要在测试环境进行测试,否则不要进行轻易的更改一次尽量只做一件事,不要受环境影响 DBA的十大任务1.了解和掌握硬件环境2.规划数据库3.安装数据库 ...

  10. mysql创建唯一索引UNIQUE INDEX,以及报错“#失败原因: [Execute: Duplicate entry '733186700' for key 'uniq_video_id_index']”

    要给t_video_prods表的video_id字段创建唯一所以,可以使用下面这条语句: alter table t_video_prods add UNIQUE INDEX `uniq_video ...