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. ready与load的区别

    JQuery里有ready和load事件 $(document).ready(function() { // ...代码... }) //document ready 简写 $(function() ...

  2. pt-osc 变更时遇到 “MySQL error 1300” 报错问题解决

    目的 线上一张表的字段长度变更 `sGuid` varchar(255) DEFAULT NULL COMMENT 'sGuid' => `sGuid` varchar(512) DEFAULT ...

  3. 【GStreamer开发】GStreamer基础教程13——播放速度

    目标 快进,倒放和慢放是trick模式的共同技巧,它们有一个共同点就是它们都修改了播放的速度.本教程会展示如何来获得这些效果和如何进行逐帧的跳跃.主要内容是: 如何来变换播放的速度,变快或者变慢,前进 ...

  4. 对String对象进行JSON序列化

    对对象进行JSON序列化,会得到类似key:value的形式. 但是如果对一个String字符串进行JSON序列化会得到什么? 测试下: public class TestMain2 {     pu ...

  5. 洛谷 题解 P2540 【斗地主增强版】

    [分析] 暴力搜顺子,贪心出散牌 为什么顺子要暴力? 玩过斗地主的都知道,并不是出越长的顺子越好,如果你有一组手牌,3,4,5,6,7,6,7,8,9,10,你一下把最长的出了去,你会单两张牌,不如出 ...

  6. 2019.12.12 Java的多线程&匿名类

    Java基础(深入了解概念为主) 匿名类 定义 Java匿名类很像局部或内联系,只是没有明细.我们可以利用匿名类,同时定义并实例化一个类.只有局部类仅被使用一次时才应该这么做. 匿名类不能有显式定义的 ...

  7. JVM(二) 栈内存结构

    栈内存是描述java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表.操作数栈.动态链接.返回出口等信息.每一个方法从调用直至执行完成的过程,就对应 ...

  8. poj1228(稳定凸包+特判最后一条边)

    题目链接:https://vjudge.net/problem/POJ-1228 题意:我是真的没看懂题意QAQ...搜了才知道.题目给了n个点,问这n个点确定的凸包是否能通过添加点来变成一个新的凸包 ...

  9. 过滤器( filter )的使用

    转自:https://www.jianshu.com/p/2ea2b0e4d1f2 过滤器通常 在 web 服务端用的比较多,有要功能 在客户端的请求访问后端资源之前,拦截这些请求. 在服务器的响应发 ...

  10. C++ 配置文件解析类 ParseConfig

    依赖项: 依赖于 ProcessString 类,可从该篇博客获取「字符串处理类 ProcessString (包含常用字符串处理函数)」 ParseConfig.h //Linux & C+ ...