前言
文章目录
文章目录
引用说明
本文参考狂神说狂神的视频以及文章,大家可以支持下狂神(狂神ElasticSearch文章地址、狂神ElasticSearch视频地址)
准备工作
安装es以及head,以及kibana,上文地址有说,上文地址
elasticSearch的基本操作
关系型数据库 | ElasticSearch |
---|---|
数据库(database) | 索引(indices) |
表(table) | 类型(types) |
行(rows) | 文档(documents) |
字段(columns) | fields |
在说操作之前,还是要先明白elasticSearch所提供的几种数据类型!
字段数据类型
-
字符串类型(text、keyword)
text:支持分词,全文检索,支持模糊、精确查询,不支持聚合,排序操作;text类型的最大支持的字符长度无限制,适合大字段存储;
keyword:不进行分词,直接索引、支持模糊、支持精确匹配,支持聚合、排序操作。keyword类型的最大支持的长度为——32766个UTF-8类型的字符,可以通过设置ignore_above指定自持字符长度,超过给定长度后的数据将不被索引,无法通过term精确匹配检索返回结果。 -
数值型(long、Integer、short、byte、double、float、half float、scaled float)
-
日期类型(date)
-
布尔类型(boolean)
-
二进制类型(binary)
1、关于索引的操作
创建索引
格式:PUT /索引名/~类型名~/文档id{请求体}
对应关系型数据库即是 数据库名/表名/行的id
例子:
PUT /test1/type1/1
{
"name":"小明",
"age":18
}
图解:
查看可视化界面
此时可以看到一些基本信息,但是如果我们想要指定“name”字段以及“age”字段的类型,那么该如何设置呢???
需要在创建索引时,指定字段的类型,如下:
# 创建规则数据库,指定字段类型
PUT /test2
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"age":{
"type": "long"
},
"birthday":{
"type": "date"
}
}
}
}
此时我们注意到并没有指定类型(数据库中称为表名,也就是上面的type1
),那么elasticSearch提供了一个默认的类型(表名):_doc
图解:
此时查看可视化界面如下:
查看索引
查看索引
往索引中插入数据
向上面创建的test2索引库中插入数据,如下(直接向默认的_doc中插入数据):
数据浏览
2、查看elasticSearch的基本信息
# 查看elasticSearch的健康状态
GET _cat/health
#查看elasticSearch的各个索引库
GET _cat/indices -v
上图:
3、更新文档
上面我们已经为test2索引库,插入了一条数据,如下:
此时我们更新数据(与其说是更新,不如说是覆盖):
对应sql语句为:update test2._doc set name='ls',age='18',birthday=null where _id=1
#修改值 索引库名/类型名/id号
PUT /test2/_doc/1
{
"name": "ls",
"age": 18
}
# 发现这种更新(覆盖)方式不适合真实需求(如果缺少字段会丢失对应的值) 状态值增加
图解:
数据浏览如下:
此时“birthday”字段值丢失。
那么如何实现只更新对应字段数据,而其他数据不影响呢???
首先还原数据,如下
# 还原数据
PUT /test2/_doc/1
{
"name": "ls",
"age": 18,
"birthday":"2000-01-02"
}
图解:
更新
#更新数据 不丢失 推荐 只修改对应的字段,其他字段不动
POST /test2/_doc/1/_update
{
"doc":{
"name": "zs"
}
}
4、删除索引、文档
插入和更新说完了,那么说说删除!
首先删除文档(一行数据):
# 删除文档(一行数据)
DELETE test2/_doc/1
结果如图
删除索引(库):
#删索引(库)
DELETE test2
结果如图
5、查询
众所周知,CRUD中最重要的还是R!!!
准备工作
首先创建一个干净的索引,然后插入几条文档,如下:
(对应数据库的理解是 创建一个叫test4的数据库,然后新建一个user表,插入三条数据)
PUT /test4/user/1
{
"name": "lxl",
"age": 21,
"dec": "大四学生",
"tags":["java","实习生","没工作","学生"]
}
PUT /test4/user/2
{
"name": "zs",
"age": 18,
"dec": "法外狂徒",
"tags":["坏人","法律","牛"]
}
PUT /test4/user/3
{
"name": "ww",
"age": 16,
"dec": "女生",
"tags":["女生","学生"]
}
执行
根据id查询指定文档
GET test4/user/1
根据指定字段精确匹配指定文档
# 获取数据 精确匹配 根据name字段查
GET test4/user/_search?q=name:lxl
# 模糊查 发现查不到 因为是精确匹配
GET test4/user/_search?q=name:lx
详细介绍,如下:
match查询
适合模糊查询,接下来的term适合精准匹配!!!
在查询之前首先明白,match是干什么的!
match匹配中,如果该字段是“text”文本类型,则会被ik分词器分析,如果是“keyword”类型则不会被分析,该类型取决于创建该type(表)时,对字段的约束(mapping)。
分析词语
GET _analyze
{
"text": "学生"
}
发现“学生”被分成了“学”和“生”两次词语,接下来的match匹配中查询dec为“学生”的文档,会匹配到dec为“女生”,因为“女生”中带有“生”这个词!!!
匹配 name字段为“ww”的文档
GET test4/user/_search
{
"query": {
"match": {
"name": "ww"
}
}
}
查询返回指定字段
匹配 name字段为“ww”的文档,并只返回name和age字段
GET test4/user/_search
{
"query": {
"match": {
"name": "ww"
}
},
"_source": ["name","age"]
}
升序或降序查询
匹配 dec字段含“学生”分词的文档,并根据年龄降序返回(升序为asc
)
GET test4/user/_search
{
"query": {
"match": {
"dec": "学生"
}
}
,"sort": [
{
"age": {
"order": "desc"
}
}
]
}
分页查询
匹配 dec字段含“学生”分词的文档,并分页返回(下标从0开始)
GET test4/user/_search
{
"query": {
"match": {
"dec": "学生"
}
}
,
"from": 0,
"size": 1
}
布尔值查询
同时满足(must)
同时满足dec中包含“学生”分词且“age”为21的文档(类似于java的and)
GET test4/user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"dec": "学生"
}
},
{
"match": {
"age": "21"
}
}
]
}
}
}
满足其一
同时满足dec中包含“学生”分词 或者 “age”为18的文档(类似于java的or)
GET test4/user/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"dec": "学生"
}
},
{
"match": {
"age": "18"
}
}
]
}
}
}
同时不满足
既不满足dec中包含“学生”分词 也不“age”为18的文档
GET test4/user/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"dec": "学生"
}
},
{
"match": {
"age": "18"
}
}
]
}
}
}
数据过滤
满足dec包含学生分词,并且age大于10的文档(gt大于、lt小于、gte大于等于、lte小于等于)
GET test4/user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"dec": "学生"
}
}
],
"filter": {
"range": {
"age": {
"gt": 10
}
}
}
}
}
}
单字段匹配多个条件
对“坏 学生”做分析,如下:
匹配 tags中带有 如上分析出的三个字的文档
GET test4/user/_search
{
"query": {
"match": {
"tags": "坏 学生"
}
}
}
term精准匹配
上面的match可以看出适合模糊查询,term适合精准匹配
首先理论基础:
term在查询时只能精确查询,match是模糊查询,而字段类型为keyword的内容不管用哪种方式,都只能精确查询
测试准备
创建一个testdb的索引(库),使用默认的_doc类型(表)并对字段类型进行约束。
PUT testdb
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"desc":{
"type": "keyword"
}
}
}
}
name字段为text类型,会进行分析,desc字段为keyword类型,无论是term还是match匹配都不会进行分析
插入几条文档:
PUT testdb/_doc/1
{
"name": "小明",
"desc": "男生"
}
PUT testdb/_doc/2
{
"name": "小红",
"desc": "女生"
}
PUT testdb/_doc/3
{
"name": "小刚",
"desc": "帅哥"
}
词语分析
为了在查询之前更加的清晰明了,首先做一下分析
# keyword类型不被分析
GET _analyze
{
"analyzer": "keyword",
"text": "小红"
}
# standard类型被分析
GET _analyze
{
"analyzer": "standard",
"text": "小红"
}
分析如图:
term精准匹配
上面的desc字段为keyword类型,接下来我们来匹配如下:
GET testdb/_search
{
"query": {
"term": {
"desc": "生"
}
}
}
GET testdb/_search
{
"query": {
"match": {
"desc": "生"
}
}
}
由于是keyword类型,只能精准匹配,所以不论是term还是match,都无法获得desc为“生”数据
高亮查询
默认高亮
接着使用上面的例子,如下:
# 高亮查询
GET testdb/_search
{
"query": {
"match": {
"name": "小明"
}
},
"highlight": {
"fields": {
"name":{}
}
}
}
如下:
自定义高亮
# 高亮查询 自定义
GET testdb/_search
{
"query": {
"match": {
"name": "小明"
}
},
"highlight": {
"pre_tags": "<p class='key',class='color=red'>",
"post_tags": "</p>",
"fields": {
"name":{}
}
}
}
如下:
至此本文结束,谢谢大家