ik分词器操作说明
1.概念
Elasticsearch虽然是一种NoSql库,但最终的目的是存储数据、检索数据。因此很多概念与MySQL类似的。
ES中的概念 | 数据库概念 | 说明 |
---|---|---|
索引库(indices) | 数据库(Database) | ES中可以有多个索引库,就像Mysql中有多个Database一样。 |
类型 | 表(table) | mysql中database可以有多个table,table用来约束数据结构。而ES中的每个索引库中只有一个类型 ,类型 中用来约束字段属性的叫做映射(mapping ) |
映射(mappings) | 表的字段约束 | mysql表对字段有约束,ES中叫做映射,用来约束字段属性,包括:字段名称、数据类型等信息 |
文档(document) | 行(Row) | 存入索引库原始的数据,比如每一条商品信息,就是一个文档。对应mysql中的每行数据 |
字段(field) | 列(Column) | 文档中的属性,一个文档可以有多个属性。就像mysql中一行数据可以有多个列。 |
因此,我们对ES的操作,就是对索引库、类型映射、文档数据的操作:
- 索引库操作:主要包含创建索引库、查询索引库、删除索引库等
- 类型映射操作:主要是创建类型映射、查看类型映射
- 文档操作:文档的新增、修改、删除、查询
1.1默认的分词器
kibana中可以测试分词器效果,我们来看看elasticsearch中的默认分词器。
在kibana的DevTools中输入一段命令:
POST /_analyze
{
"text": "欧阳xx真的太帅了",
"analyzer": "standard"
}
请求代表的含义:
- 请求方式:
POST
- 请求路径:
_analyze
,前面省略了http://127.0.0.1:9200,这个由Kibana帮我们补充 - 请求参数:JSON风格,包含两个属性:
analyzer
:分词器名称,standard是默认的标准分词器text
:要分词的文本内容
效果:非常的垃圾,一个字一组不看也罢.
1.2 中文分词
标准分词器并不能很好处理中文,一般我们会用第三方的分词器,例如:IK分词器。
IK分词器的 地址:https://github.com/medcl/elasticsearch-analysis-ik, 安装非常简单。
把课前资料中的zip包:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xcdja4wT-1599202647675)(F:/%E9%A3%9E%E7%A7%8B%E7%A7%8D%E5%AD%90%E4%B8%8B%E8%BD%BD/%E9%A1%B9%E7%9B%AE%E4%BA%8C%E5%89%8D%E7%BD%AE/Spring-Boot_%E7%AC%AC%E4%B8%80%E5%A4%A9.%E8%AF%BE%E5%A0%82/%E9%A2%84%E4%B9%A0%E7%AC%94%E8%AE%B0/day03-Elasticsearch01/assets/image-20200103101914300-1590741940714.png)]
解压到Elasticsearch目录的plugins目录中,并重命名为ik:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M9OQSqmN-1599202647679)(F:/%E9%A3%9E%E7%A7%8B%E7%A7%8D%E5%AD%90%E4%B8%8B%E8%BD%BD/%E9%A1%B9%E7%9B%AE%E4%BA%8C%E5%89%8D%E7%BD%AE/Spring-Boot_%E7%AC%AC%E4%B8%80%E5%A4%A9.%E8%AF%BE%E5%A0%82/%E9%A2%84%E4%B9%A0%E7%AC%94%E8%AE%B0/day03-Elasticsearch01/assets/image-20200103102056432.png)]
然后重启elasticsearch:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zh2y3kcd-1599202647681)(F:/%E9%A3%9E%E7%A7%8B%E7%A7%8D%E5%AD%90%E4%B8%8B%E8%BD%BD/%E9%A1%B9%E7%9B%AE%E4%BA%8C%E5%89%8D%E7%BD%AE/Spring-Boot_%E7%AC%AC%E4%B8%80%E5%A4%A9.%E8%AF%BE%E5%A0%82/%E9%A2%84%E4%B9%A0%E7%AC%94%E8%AE%B0/day03-Elasticsearch01/assets/1526523386610.png)]
IK分词器加载成功了!
再次运行命令,不过把分词器换成IK:
POST /_analyze
{
"text": "欧阳xx真的太帅了",
"analyzer": "ik_smart"
}
IK分词器可以用ik_max_word和ik_smart两种方式,分词粒度不同。
效果:明显好了很多,当然这也是语句中词语较少的原因.
{
"tokens" : [
{
"token" : "欧阳",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "x",
"start_offset" : 2,
"end_offset" : 3,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "x",
"start_offset" : 3,
"end_offset" : 4,
"type" : "CN_CHAR",
"position" : 2
},
{
"token" : "真的",
"start_offset" : 4,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "太帅",
"start_offset" : 6,
"end_offset" : 8,
"type" : "CN_WORD",
"position" : 4
},
{
"token" : "了",
"start_offset" : 8,
"end_offset" : 9,
"type" : "CN_CHAR",
"position" : 5
}
]
1.3.Rest的API介绍
操作MySQL,主要是database操作、表操作、数据操作,对应在elasticsearch中,分别是对索引库操作、类型映射操作、文档数据的操作:
- 索引库操作:主要包含创建索引库、查询索引库、删除索引库等
- 类型映射操作:主要是创建类型映射、查看类型映射
- 文档操作:文档的新增、修改、删除、查询
而ES中完成上述操作都可以通过Rest风格的API来完成,符合请求要求的Http请求就可以完成数据的操作,详见官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
下面我们分别来学习。
2 ES的索引库操作
按照Rest风格,增删改查分别使用:POST、DELETE、PUT、GET等请求方式,路径一般是资源名称。因此索引库操作的语法类似。
2.1 创建索引库
创建索引库的请求格式:
-
请求方式:PUT
-
请求路径:/索引库名
-
请求参数:json格式:
{ "settings": { "属性名": "属性值" } }
settings:就是索引库设置,其中可以定义索引库的各种属性,目前我们可以不设置,都走默认。
说明:{
“zhouls” : {
“settings” : {
“index” : {
“creation_date” : “1488203759467”,
“uuid” : “Sppm-db_Qm-OHptOC7vznw”,
“number_of_replicas” : “1”,
“number_of_shards” : “5”,
“version” : {
“created” : “2040399”
}
}
}
}
}
settings修改索引库默认配置
例如:分片数量,副本数量
查看:curl -XGET http://192.168.80.10:9200/zhouls/_settings?pretty
操作不存在索引:curl -XPUT ‘192.168.80.10:9200/liuch/’ -d’{“settings”:{“number_of_shards”:3,“number_of_replicas”:0}}’
操作已存在索引:curl -XPUT ‘192.168.80.10:9200/zhouls/_settings’ -d’{“index”:{“number_of_replicas”:1}}’
总结:就是,不存在索引时,可以指定副本和分片,如果已经存在,则只能修改副本。
在创建新的索引库时,可以指定索引分片的副本数。默认是1,这个很简单
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ieUrIckr-1599202647685)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599136990257.png)]
如上直接创建索引库使用默认配置即可.
删除索引库
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PTNI1nYG-1599202647686)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599137075037.png)]
2.2 总结
索引库操作:
- 创建索引库:
PUT /库名称
- 查询索引库:
GET /索引库名称
- 删除索引库:
DELETE /索引库名称
3.类型映射
MySQL中有表,并且表中有对字段的约束,对应到elasticsearch中就是类型映射mapping
.
3.1.映射属性
索引库数据类型是松散的,不过也需要我们指定具体的字段及字段约束信息。而约束字段信息的就叫做映射(mapping
)。
映射属性包括很多:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vFo9SFgu-1599202647688)(F:/%E9%A3%9E%E7%A7%8B%E7%A7%8D%E5%AD%90%E4%B8%8B%E8%BD%BD/%E9%A1%B9%E7%9B%AE%E4%BA%8C%E5%89%8D%E7%BD%AE/Spring-Boot_%E7%AC%AC%E4%B8%80%E5%A4%A9.%E8%AF%BE%E5%A0%82/%E9%A2%84%E4%B9%A0%E7%AC%94%E8%AE%B0/day03-Elasticsearch01/assets/image-20200529170444227.png)]
参考官网:https://www.elastic.co/guide/en/elasticsearch/reference/7.x/mapping-params.html
elasticsearch字段的映射属性该怎么选,一般要考虑这样几个问题:
-
1)数据的类型是什么?
- 这个比较简单,根据字段的含义即可知道,可以通过
type
属性来指定
- 这个比较简单,根据字段的含义即可知道,可以通过
-
2)数据是否参与搜索?
- 参与搜索的字段将来需要创建倒排索引,作为搜索字段。可以通过
index
属性来指定是否参与搜索,默认为true,也就是每个字段都参与搜索
- 参与搜索的字段将来需要创建倒排索引,作为搜索字段。可以通过
-
3)数据存储时是否需要分词?
- 一个字段的内容如果不是一个不可分割的整体,例如国家,一般都需要分词存储。
-
4)如果分词的话用什么分词器?
- 分词器类型很多,中文一般选择IK分词器
- 指定分词器类型可以通过
analyzer
属性指定
2.2.数据类型
elasticsearch提供了非常丰富的数据类型:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3rXrbcd6-1599202647689)(F:/%E9%A3%9E%E7%A7%8B%E7%A7%8D%E5%AD%90%E4%B8%8B%E8%BD%BD/%E9%A1%B9%E7%9B%AE%E4%BA%8C%E5%89%8D%E7%BD%AE/Spring-Boot_%E7%AC%AC%E4%B8%80%E5%A4%A9.%E8%AF%BE%E5%A0%82/%E9%A2%84%E4%B9%A0%E7%AC%94%E8%AE%B0/day03-Elasticsearch01/assets/image-20200529170805336.png)]
比较常见的有:
- string类型,又分两种:
- text:可分词,存储到elasticsearch时会根据分词器分成多个词条
- keyword:不可分词,数据会完整的作为一个词条
- Numerical:数值类型,分两类
- 基本数据类型:long、interger、short、byte、double、float、half_float
- 浮点数的高精度类型:scaled_float
- 需要指定一个精度因子,比如10或100。elasticsearch会把真实值乘以这个因子后存储,取出时再还原。
- Date:日期类型
- Object:对象,对象不便于搜索。因此ES会把对象数据扁平化处理再存储。
如果创建如下信息存储到文档中 name:欧阳 , interest:美女与金钱 sex :男
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iIc45V1I-1599202647690)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599138035444.png)]
分别建立了三种约束,name,interest,sex.type
为分词属性,keyword
为不可分词,名字与性别这种不需要拆分的即选择keyword,interest
则选择文本类型,可以继续分词,
index
默认为true,不需要时再选择false,一些特殊信息不需要搜索时.
analyzer
:兴趣爱好一般较多,查询时需要分词,所以指定了IK分词器
没有索引库时要做一点改动:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ULtMf7tG-1599202647691)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599138779832.png)]
新增内容:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vA2U80p6-1599202647692)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599139180799.png)]
根据id查看索引库:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9xd0e6cf-1599202647693)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599139287728.png)]
put post的区别:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1XPGmgz0-1599202647694)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599139493032.png)]
put与post都可以进行新增与修改, 但是put必须添加id如上post的方法,如果有id则修改, 没有则新增
post不携带id也可以, 携带id与put一样.
4.查询
3.1.基本查询
elasticsearch提供的查询方式有很多,例如:
- 查询所有
- 分词查询
- 词条查询
- 模糊查询
- 范围查询
- 布尔查询
虽然查询的方式有很多,但是基本语法是一样的:
基本语法
GET /索引库名/_search
{
"query":{
"查询类型":{
"查询条件":"查询条件值"
}
}
}
这里的query代表一个查询对象,里面可以有不同的查询属性
- 查询类型,有许多固定的值,如:
- match_all:查询所有
- match:分词查询
- term:词条查询
- fuzzy:模糊查询
- range:范围查询
- bool:布尔查询
- 查询条件:查询条件会根据类型的不同,写法也有差异,后面详细讲解
3.2.查询案例
3.2.1 查询所有内容:
GET /people/_search
{
"query":
{
"match_all":{}
}
}
//结果:
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "people",
"_type" : "_doc",
"_id" : "SFc0VHQB3WLQXpQwiRkZ",
"_score" : 1.0,
"_source" : {
"name" : "陈x",
"interest" : "未成年与小学生",
"sex" : "男"
}
},
{
"_index" : "people",
"_type" : "_doc",
"_id" : "SVc1VHQB3WLQXpQwdxk2",
"_score" : 1.0,
"_source" : {
"name" : "吴翼",
"interest" : "撸管与橡皮人",
"sex" : "男"
}
},
{
"_index" : "people",
"_type" : "_doc",
"_id" : "R1cdVHQB3WLQXpQw-xl6",
"_score" : 1.0,
"_source" : {
"name" : "欧阳",
"interest" : "美女金钱",
"sex" : "男"
}
}
]
}
}
说明:
- took:查询花费时间,单位是毫秒
- time_out:是否超时
- _shards:分片信息
- hits:搜索结果总览对象
- total:搜索到的总条数
- max_score:所有结果中文档得分的最高分
- hits:搜索结果的文档对象数组,每个元素是一条搜索到的文档信息
- _index:索引库
- _type:文档类型
- _id:文档id
- _score:文档得分
- _source:文档的源数据
- 3.2.2 分词查询match
match
类型查询,会把查询条件进行分词,然后进行查询,多个词条之间默认是or的关系
语法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ckVVgDZo-1599202647694)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599184063436.png)]
FIELD 代表字段,即我们定义的name等,text为查询内容 match_all可以看成是一个查询内容为空的查询.
这里不妨尝试下把match打括号内的内容去掉,看看是否与match_all语法一样,结果 报错了,显然两者语法不一样,不然也没有多一个match_all的必要的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wOX2czxB-1599202647695)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599185788104.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nd3DKn5Q-1599202647696)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599185863443.png)]
注意: 查询内容与分词有关, 如上两图,未成年是一个词未是一个词, 所以查询未找不到未成年,如果分词器进行将词进行细拆分是可以找到的. 另外姓名是keyword类型,是不可能拆分的, 单独搜索一个陈与吴都是搜不到的.
3.2.2 精确查找
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NQ2pOyR7-1599202647697)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599186171870.png)]
当需要根据内容进行精确查找时,可以使用operator加and, 这样就会根据内容进行精确查找
3.2.3 模糊查询
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EhAWDC4L-1599202647697)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599187287639.png)]
value匹配模糊查询的内容, fuzziness 匹配模糊的数量,当匹配数量和内容一样多时,那么久变成了无条件查询所有的效果.如下图, 模糊查询容易导致查询多次,千万注意使用模糊查询
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vo0MzeA5-1599202647699)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599187426236.png)]
3.2.4 范围查询range
range
查询找出那些落在指定区间内的数字或者时间
# 范围查询
GET /people/_search
{
"query": {
"range": {
"price": {
"gte": 1000,
"lt": 2800
}
}
}
}
range
查询允许以下字符:
操作符 | 说明 |
---|---|
gt | 大于 |
gte | 大于等于 |
lt | 小于 |
lte | 小于等于 |
3.2.5 词条匹配term
term
查询,词条查询。查询的条件是一个词条,不会被分词。可以是keyword类型的字符串、数值、或者text类型字段中分词得到的某个词条.
GET /people/_search
{
"query": {
"term": {
"name": {
"value": "陈x"
}
}
}
}
3.3 排序
排序、高亮、分页并不属于查询的条件,因此并不是在query
内部,而是与query
平级,基本语法:
GET /{索引库名称}/_search
{
"query": { ... },
"sort": [
{
"{排序字段}": {
"order": "{asc或desc}"
}
}
]
}
sort
可以让我们按照不同的字段进行排序,并且通过order
指定排序的方式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZXTouuSG-1599202647700)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599190373260.png)]
查询的语法与排序是并列关系,相互不产生影响.
3.4 搜索词高亮显示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mcYEEEB1-1599202647701)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599201325407.png)]
与query并列,标签内容可以根据需求改动
3.5_source
筛选
默认情况下,elasticsearch在搜索的结果中,会把文档中保存在_source
的所有字段都返回。
如果我们只想获取其中的部分字段,我们可以添加_source
的过滤
3.5.1.直接指定字段
示例:
GET /people/_search
{
"_source": ["name","interest"],
"query": {
"term": {
"sex": "男
}
}
}
返回的结果:
3.5.2 指定includes和excludes
我们也可以通过:
- includes:来指定想要显示的字段
- excludes:来指定不想要显示的字段
二者都是可选的。
示例:
排序的方式
[外链图片转存中…(img-ZXTouuSG-1599202647700)]
查询的语法与排序是并列关系,相互不产生影响.
3.4 搜索词高亮显示
[外链图片转存中…(img-mcYEEEB1-1599202647701)]
与query并列,标签内容可以根据需求改动
3.5_source
筛选
默认情况下,elasticsearch在搜索的结果中,会把文档中保存在_source
的所有字段都返回。
如果我们只想获取其中的部分字段,我们可以添加_source
的过滤
3.5.1.直接指定字段
示例:
GET /people/_search
{
"_source": ["name","interest"],
"query": {
"term": {
"sex": "男
}
}
}
返回的结果:
3.5.2 指定includes和excludes
我们也可以通过:
- includes:来指定想要显示的字段
- excludes:来指定不想要显示的字段
二者都是可选的。
示例:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DkPSGlkB-1599202647701)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1599202496104.png)]