一、索引语法

  • 创建索引

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