ElasticSearch基本增删改查DSL语法
一、索引语法
-
创建索引
PUT article
-
查看所有索引简略信息
GET _cat/indices?v
表头 | 含义 |
---|---|
health | 当前服务器健康状态:green(集群完整) yellow(单点正常、集群不完整) red(单点不正常) |
status | 索引打开、关闭状态 |
index | 索引名 |
uuid | 索引统一编号 |
pri | 主分片数量 |
rep | 副本数量 |
docs.count | 可用文档数量 |
docs.deleted | 文档删除状态(逻辑删除) |
store.size | 主分片和副分片整体占空间大小 |
pri.store.size | 主分片占空间大小 |
-
查看所有索引详细信息
GET _all
-
查询索引属性(指定索引名称)
GET article
-
设置Mapping
1、mapping字段类型
一级分类 | 二级分类 | 具体类型 |
---|---|---|
核心类型 | 字符串类型 | string,text,keyword |
整数类型 | integer,long,short,byte | |
浮点类型 | double,float,half_float,scaled_float | |
逻辑类型 | boolean | |
日期类型 | date | |
范围类型 | range | |
二进制类型 | binary | |
复合类型 | 数组类型 | array |
对象类型 | object | |
嵌套类型 | nested | |
地理类型 | 地理坐标类型 | geo_point |
地理地图 | geo_shape | |
特殊类型 | IP类型 | ip |
范围类型 | completion | |
令牌计数类型 | token_count | |
附件类型 | attachment | |
抽取类型 | percolator |
2、创建时就设置mapping
PUT article
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"title": {
"type": "keyword"
},
"md_content": {
"type": "text"
},
"html_content": {
"type": "text"
},
"summary": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"view_count": {
"type": "integer"
},
"status": {
"type": "integer"
},
"is_top": {
"type": "integer"
},
"category_id": {
"type": "keyword"
},
"sort": {
"type": "integer"
},
"publish_date": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"create_by": {
"type": "keyword"
},
"create_time": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"update_by": {
"type": "keyword"
},
"update_time": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
3、先创建后设置mapping
PUT article/_mapping
{
"properties": {
"id": {
"type": "keyword"
},
"title": {
"type": "keyword"
},
"md_content": {
"type": "text"
},
"html_content": {
"type": "text"
},
"summary": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"view_count": {
"type": "integer"
},
"status": {
"type": "integer"
},
"is_top": {
"type": "integer"
},
"category_id": {
"type": "keyword"
},
"sort": {
"type": "integer"
},
"publish_date": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"create_by": {
"type": "keyword"
},
"create_time": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"update_by": {
"type": "keyword"
},
"update_time": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
-
查询所有索引下的数据(空查询,不推荐)
GET _search
-
查询article索引下的所有数据
GET article/_search
携带版本号
GET article/_search?version=true
-
删除索引
DELETE article
二、文档基础语法
-
创建文档
POST article/_doc 随机 _id
POST article/_doc/1 指定 _id
{
"id":"1000000000001",
"title":"测试标题",
"md_content":"MD正文内容xxxxxxxxxxxxxxxx",
"html_content":"HTML正文内容xxxxxxxxxxxxxxxx",
"summary":"这是文章摘要",
"view_count":156,
"status":0,
"is_top":0,
"category_id":"2000000022001",
"sort":0,
"publish_date":"2021-11-17 17:11:28",
"create_by":"3330000000001",
"create_time":"2021-11-17 17:11:28",
"update_by":"3330000000001",
"update_time":"2021-11-17 17:11:28"
}
-
查看文档(全部文档)
GET article/_search
-
查看文档(_id查询)
GET article/_doc/1
-
全量修改( 覆盖)
POST article/_doc/1
{
"id":"1000000000001",
"title":"全量修改测试xxxxxxxxxxx",
"md_content":"MD正文内容xxxxxxxxxxxxxxxx",
"html_content":"HTML正文内容xxxxxxxxxxxxxxxx",
"summary":"这是文章摘要",
"view_count":156,
"status":0,
"is_top":0,
"category_id":"2000000022001",
"sort":0,
"publish_date":"2021-11-17 17:11:28",
"create_by":"3330000000001",
"create_time":"2021-11-17 17:11:28",
"update_by":"3330000000001",
"update_time":"2021-11-17 17:11:28"
}
-
修改文档(部分字段修改)
POST article/_update/1
{
"doc":{
"title":"测试指定字段修改xxxx"
}
}
-
更新时 retry_on_conflict 参数重试次数
retry_on_conflict 指定重试次数
POST /article/_doc/1/_update?retry_on_conflict=3
{
"doc": {
"title": "测试 retry_on_conflict参数 "
}
}
与 _version结合使用
POST /article/_doc/1/_update?retry_on_conflict=3&version=22&version_type=external
{
"doc": {
"title": "测试 retry_on_conflict参数 与 _version"
}
}
-
删除文档
DELETE article/_doc/1
这里的id是指文档自带的 _id
字段。
条件更新
POST article/_update_by_query
{
"query": {
"bool": {
"must": [
{
"term": {
"name.keyword": "zhangsan"
}
},
{
"term": {
"age": "30"
}
}
]
}
},
"script": {
"source": "ctx._source.age=\"18\";ctx._source.nickname=\"张三丰\""
}
}
脚本更新
更新单个文档 多个语句之间用";"隔开就可以
POST article/doc/1/_update
{
"script":"ctx._source.status = 10;ctx._source.open_time = '2020-02-24 15:48:20'"
}
根据条件更新文档
POST article/_update_by_query
{
"query": {
"bool": {
"filter": [
{
"term": {
"person_id": {
"value": "2496800"
}
}
}
]
}
},
"script": {
"inline": """
def appId = ctx._source.wechat_appid;
def nId = params.appid;
if(appId == null) {
ctx._source.wechat_appid = nId;
} else if (!(appId instanceof List) && appId != nId) {
List arr = new ArrayList();
arr.add(appId);
arr.add(nId);
ctx._source.wechat_appid = arr;
}
"""
,
"params":{
"appid":"12311"
}
}
}
删除文档(条件删除)
POST article/_delete_by_query
{
"query":{
"match":{
"name.keyword":"地界1"
}
}
}
三、文档查询语法
基础数据
PUT student
POST /student/_doc/1001
{
"name":"zhangsan",
"nickname":"zhangsan",
"sex":"男",
"age":30
}
POST /student/_doc/1002
{
"name":"lisi",
"nickname":"lisi",
"sex":"男",
"age":20
}
POST /student/_doc/1003
{
"name":"wangwu",
"nickname":"wangwu",
"sex":"女",
"age":40
}
POST /student/_doc/1004
{
"name":"zhangsan1",
"nickname":"zhangsan1",
"sex":"女",
"age":50
}
POST /student/_doc/1005
{
"name":"zhangsan2",
"nickname":"zhangsan2",
"sex":"女",
"age":30
}
-
查询所有文档
GET student/_search { "query": { "match_all": {} } }
-
简单条件查询
GET /student/_search?q=name:zhangsan2&from=0&size=1&sort=age:desc,name.keyword:asc
q: 查询条件 字段名:字段值
from: 分页查询起始 (page - 1) * pageName
size: 展示条数
sort: 排序
-
匹配查询
GET student/_search
{
"query": {
"match": {
"name": "zhangsan"
}
}
}
# match 匹配类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是 or 的关系
-
字段匹配查询
GET student/_search
{
"query": {
"multi_match": {
"query": "zhangsan",
"fields": ["name","nickname"]
}
}
}
# multi_match 与 match 类似,不同的是它可以在多个字段中查询
这里查询的意思是:查name等于zhangsan 或者 nickname等于zhangsan 的数据
-
关键字精确查询(term)
GET student/_search
{
"query": {
"term": {
"name": {
"value": "zhangsan"
}
}
}
}
# term 查询,精确的关键词匹配查询,不对查询条件进行分词=
-
多关键字精确查询(terms)
GET student/_search
{
"query": {
"terms": {
"name": ["zhangsan","lisi"]
}
}
}
# terms 查询和 term 查询一样,但它允许你指定多值进行匹配。
# 如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件,类似于 mysql 的 in
-
指定查询字段
GET student/_search
{
"query":{
"terms":{
"nickname":["zhangsan"]
}
},
"_source":["name","nickname"]
}
# 默认情况下,Elasticsearch 在搜索的结果中,会把文档中保存在_source 的所有字段都返回。
# 如果我们只想获取其中的部分字段,我们可以添加_source 的过滤
-
过滤字段
# includes:来指定想要显示的字段
# excludes:来指定不想要显示的字段
GET student/_search
{
"query":{
"terms":{
"name":["zhangsan"]
}
},
"_source":{
"includes":["name"]
}
}
#如果同时使用 includes 和excludes,会先用includes取出字段,然后再移除excludes的字段 例如:
"_source":{
"includes":["name","nickname"],
"excludes":["name"]
}
#这种情况includes显示name和nickname,但是excludes排除掉了name,所以最后显示的只有nickname字段
-
查询存在字段(exists)
#查询包含 name 字段的文档
GET student/_search
{
"query": {
"exists": {
"field": "name"
}
}
}
-
ids( sql in 查询)
GET student/_search { "query": { "ids": { "values": ["1001","1002"] } } }
-
前缀查询(prefix )
GET student/_search
{
"query": {
"prefix": {
"nickname": { #要查询的字段名
"value": "zhang"
}
}
}
}
-
regexp query 正则查询
GET student/_search
{
"query": {
"regexp": {
"nickname": {
"value": "z.*n", # .* 表示通配符
"flags": "ALL",
"max_determinized_states": 10000,
"rewrite": "constant_score"
}
}
}
}
-
组合查询
GET student/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "zhangsan"
}
}
],
"must_not": [
{
"match": {
"age": 40
}
}
],
"should": [
{
"match":{
"sex": "男"
}
},
{
"match": {
"sex": "女"
}
}
]
}
}
}
# `bool`把各种其它查询通过
# `must`(必须 )
# `must_not`(必须不)
# `should`(应该)(多个满足一个即可)的方式进行组合
-
范围查询
操作符 | 说明 |
---|---|
gt | 大于 > |
gte | 大于等于 >= |
lt | 小于 < |
lte | 小于等于 <= |
#range 查询找出那些落在指定区间内的数字或者时间。range 查询允许以上字符
GET student/_search
{
"query": {
"range": {
"age": {
"gte": 30,
"lte": 35
}
}
}
}
-
模糊查询
# 返回包含与搜索字词相似的字词的文档。
# 编辑距离是将一个术语转换为另一个术语所需的一个字符更改的次数。这些更改可以包括:
# 更改字符(box → fox)
# 删除字符(black → lack)
# 插入字符(sic → sick)
# 转置两个相邻字符(act → cat)
# 为了找到相似的术语,fuzzy 查询会在指定的编辑距离内创建一组搜索词的所有可能的变体或扩展。然后查询返回每个扩展的完全匹配。
# 通过 fuzziness 修改编辑距离。一般使用默认值 AUTO,根据术语的长度生成编辑距离。
GET student/_search
{
"query": {
"fuzzy": {
"nickname": {
"value": "zhangsa1n",
"fuzziness": 2
}
}
}
}
-
排序
# sort 可以让我们按照不同的字段进行排序,并且通过 order 指定排序的方式。desc 降序,asc升序。
# 单字段
GET student/_search
{
"query": {
"match": {
"name": "zhangsan"
}
},
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
# 多字段
GET student/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"age": {
"order": "desc"
}
},
{
"_id":{
"order": "asc"
}
}
]
}
-
高亮查询
# 在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮
# Elasticsearch 可以对查询内容中的关键字部分,进行标签和样式(高亮)的设置。
# 在使用 match 查询的同时,加上一个 highlight 属性:
# fragment_size :指定高亮数据展示多少个字符回来;
# pre_tags:指定前缀标签,如 <font color="red">
# post_tags:指定后缀标签,如 </font>
# fields:指定那个字段为高亮字段
GET student/_search
{
"query": {
"match": {
"name": "zhangsan"
}
},
"highlight": {
"fields": {
"nickname": {}
},
"pre_tags": "<font color='red'>",
"post_tags": "</font>",
"fragment_size": 10
}
}
-
分页查询
# from:当前页的起始索引,默认从 0 开始。 from = (pageNum - 1) * size
# size:每页显示多少条
GET student/_search
{
"query": {
"match": {
"name": "zhangsan"
}
},
"sort": [
{
"age":{
"order": "desc"
}
}
],
"from": 0,
"size": 2
}
-
聚合查询
-
aggs
说明采用的是聚合查询 -
max_age
是聚合查询的名称 -
max
是函数,还有 min 、 avg 等等 -
field
指定需要统计的字段。
-
# 聚合允许使用者对 es 文档进行统计分析,类似与关系型数据库中的 group by,当然还有很多其他的聚合,例如取最大值、平均值、求和等等。
# 最大值
GET student/_search
{
"aggs": {
"max_age": {
"max":{
"field": "age"
}
},
"avg_age": {
"avg": {
"field": "age"
}
}
},
"size": 0 #设置size为0,否则文档数据也会查出来
}
# 对某个字段的值进行去重之后再取总数
GET student/_search
{
"aggs": {
"distinct_age": {
"cardinality": {
"field": "age"
}
}
},
"size": 0
}
# State 聚合 stats 聚合,对某个字段一次性返回 count,max,min,avg 和 sum 五个指标
GET student/_search
{
"aggs": {
"stats_age": {
"stats": {
"field": "age"
}
}
},
"size": 0
}
-
桶聚合查询
# 桶聚和相当于 sql 中的 group by 语句
# terms 聚合,分组统计
GET student/_search
{
"aggs": {
"age_groupby": {
"terms": {
"field": "age"
}
}
},
"size": 0
}
# 在 terms 分组下再进行聚合
GET student/_search
{
"aggs": {
"age_groupby": {
"terms": {
"field": "age"
},
"aggs": {
"sum_age": {
"sum": {
"field": "age"
}
}
}
}
},
"size": 0
}
-
Scroll分批查询
场景:下载某一个索引中1亿条数据,到文件或是数据库。
不能一下全查出来,系统内存溢出。所以使用scoll滚动搜索技术,一批一批查询。
scoll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后只会基于该旧的视图快照提供数据搜索,如果这个期间数据变更,是不会让用户看到的
每次发送scroll请求,我们还需要指定一个scoll参数,指定一个时间窗口,每次搜索请求只要在这个时间窗口内能完成就可以了。
GET /book/_search?scroll=1m
{
"query": {
"match_all": {}
},
"size": 3
}
返回
{
"_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAMOkWTURBNDUtcjZTVUdKMFp5cXloVElOQQ==",
"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" : [
]
}
}
获得的结果会有一个scoll_id,下一次再发送scoll请求的时候,必须带上这个scoll_id
GET /_search/scroll
{
"scroll": "1m",
"scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAMOkWTURBNDUtcjZTVUdKMFp5cXloVElOQQ=="
}
与分页区别:
分页给用户看的 deep paging
scroll是用户系统内部操作,如下载批量数据,数据转移。零停机改变索引映射。
https://blog.csdn.net/weixin_43939924/article/details/122154537
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 奇怪的阿峰
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果