ElasticSearch开发指北和场景题分析
前言
常用操作
以下操作均使用ES的API进行展示,为什么这么做呢,而不是选用某一个程序代码来进行演示?原因是我认为,ES的核心在于API,无论是Java、python等包装的操作客户端,哪怕语法用得再厉害,无非就是对原生Restful API的封装罢了。再说了大部分客户端都支持直接丢个Json进去,你掌握了API的写法,其实用什么语言都能很快上手。
索引操作
创建索引--最基础的操作,一般建议是直接如下案例,一次性建好配置和映射还有别名,避免多次IO
PUT /索引名称 { "settings": { "属性名": "属性值" } }
PUT /flink-test1
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"refresh_interval": "1s",
"translog.durability": "async",
"translog.sync_interval": "5s",
"index.highlight.max_analyzed_offset": 2000000
},
"aliases": {
"flink-test": {}
},
"mappings": {
"properties": {
"userId": {
"type": "keyword"
},
"userName": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"requestUrl": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"requestType": {
"type": "keyword"
},
"logType": {
"type": "keyword"
},
"requestMethod": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"env": {
"type": "keyword"
},
"localIp": {
"type": "keyword",
"index": false,
"doc_values": false
},
"requestIp": {
"type": "keyword",
"index": false,
"doc_values": false
},
"triceId": {
"type": "keyword"
},
"createTime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss.SSS"
},
"system": {
"type": "keyword"
},
"threadName": {
"type": "keyword"
},
"msg": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
}
}
判断索引是否存在--HEAD /索引名称
查看索引--GET ****/索引名称
批量查看索引--GET ****/索引名称1,索引名称2,索引名称3,...
查看所有索引--GET _all
概要信息-- GET /_cat/indices?v
查询主节点--GET /_cat/master
打开索引--POST /索引名称/_open
关闭索引--POST /索引名称/_close
删除索引--DELETE /索引名称1,索引名称2,索引名称3...
创建映射 字段
PUT /索引库名/_mapping
{
"properties": {
"字段名": {
"type": "类型",
"index": true,
"store": true,
"analyzer": "分词器"
}
}
}
查看映射关系--GET ****/索引名称/_mapping
一次性创 建索引和映射
PUT /索引库名称
{
"settings":{
"索引库属性名":"索引库属性值"
},
"mappings":{
"properties":{
"字段名":{
"映射属性名":"映射属性值"
}
}
}
}
查看索引配置--GET ****/索引名称/_settings
修改索引 配置
PUT /log-zero-uat-202211/_settings
{
"index" : {
"highlight.max_analyzed_offset" : 500000
}
}
文档操作
新增文档--第一种指定ID,不推荐,建议使用第二种不指定ID,由ES自动生成
POST /索引名称/_doc/{id}
POST /test111/_doc
{
"name" : "百度",
"job" : "小度用户运营经理",
"payment" : "30000"
}
查看单个文档--GET ****/索引名称/_doc/{id}
查看所有 文档
POST /索引名称/_search
{
"query":{
"match_all": {}
}
}
查询指定列--GET /索引名称/_doc/1?_source=name,job
更新文档
全部更新,是直接把之前的老数据,标记为删除状态,然后,再添加一条更新的(使用PUT或者POST)局域更新,只是修改某个字段(使用POST)
全部更新
把刚才新增的请求方式改为PUT,就是修改了,不过修改必须指定id,如果id对应文档存在,则修改;如果id对应文档不存在,则新增
局部更新
POST /索引名/_update/{id}
{
"doc":{
"field":"value"
}
}
删除文档
根据id进行删除:
DELETE /索引名/_doc/{id}
删除所有文档
POST /my-index-000001/_delete_by_query
{
"query": {
"match": {
"user.id": "elkbee"
}
}
}
查询日期 大于XXX的字段
GET /log-zero-pro-202203-alias1/_search
{
"query": {
"bool": {
"filter": [
{ "range": { "createTime": { "gte": "2022-03-31 08:00:00.000" }}}
]
}
}
}
方案操作文档
常规操作还有很多,后面慢慢补充吧,没有放很多复杂的东西进去,毕竟大家的业务都不一样,照着官网案例写就行了,我觉得8.X的文档写的比7.X的垃圾多了,不知道是不是我的错觉,少了很多案例。下面带来一些经典的ES实操案例,让大家快速了解ES。
ES集群添加插件(分词器)或修改配置-需要滚动重启
- 禁止分片自动分布。这个很好理解,避免新节点进来,分片数据重分配,不会影响数据的正确性,同时不用重分配也加速了咱们切换的时间。
PUT /_cluster/settings
{
"transient" : {
"cluster.routing.allocation.enable" : "none"
}
}
- 执行同步刷新。在关闭节点前,把内存中的数据刷入磁盘,避免丢失数据。
curl -X POST "localhost:9200/_flush/synced"
/_flush/synced API的主要的作用和场景有:
- 强制执行挂起的索引刷新,使文档可搜索。默认情况下,Elasticsearch会定期自动刷新,但调用/_flush/synced可以手动刷新。
- 在做故障转移之前,调用该API可以确保主分片已经完成所有的索引操作。否则故障转移可能会失去数据。
- 与_flush不同,_synced会进行额外的处理,确保主分片和副本分片都完成了刷新。
- 关闭单个节点,添加分词器或者修改配置之类的,重启节点
- 观察该节点是否加入集群,检查下是否正常启动,都OK,就开启分片自动分片,等待集群状态恢复正常
PUT /_cluster/settings
{
"transient" : {
"cluster.routing.allocation.enable" : "all"
}
}
- 对剩余节点进行以上1-4重复操作,即可完成滚动重启
ES集群重建索引-无需重启
Elasticsearch时区问题
Elasticsearch 滞后8个小时等时区问题,一网打尽!
推荐上面那篇文章,大佬写得很好,总结一下就是,ES默认时区UTC+0改不了,只能适应它,但是Kibana和查询API可以换时区曲线救国。当然我们不能指望查询时去改数据,最好做到输入到ES里的数据就是我们想要的时区。
第二种是向ES发送请求时,比如是Java客户端,在JSON转换时加上时区@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSS",timezone="GMT+8"),注意我这里用的是Jackson序列化工具,所以注解用的JsonFormat,如果Spring全局替换为Fastjson就改下注解就行。
ES字段调整的另一个办法
不必Reindex,利用runtime_fields优雅地解决字段类型错误问题
这是ES社区写的一篇文章,里面提到了这个运行时字段,是ES较高版本给出的一个解决措施。里面只提到了它的优点,就是灵活性强且不占用存储空间,因为他是在查询期间动态运算的,所以运行时字段并不在实际的文档中存储。也就是说,你加了这个运行时字段,其实索引大小是不会变的,但是查询的时候,可以用这个字段查出数据,特定情况也算是提高了性能,如果是频繁修改索引的业务场景,那么使用运行时字段,就不会引发索引的频繁构建。
但是文章里没说缺点,这就很坑人了,所以我来说说。运行时处理,由这个关键词很容易想到,这是一种时间换空间的手法,必然会拉长查询速度,同时耗费多余的计算资源。总之使用的时候见仁见智吧,和前面的滚动停机以及不停机的两种方案各有优劣。
写在最后
有一段时间没更新啦,本次带来的是一波小更新,下次见喔!上周属实太忙了,本打算更新的,结果因为上班太忙就没空了,这几天应该会整理一波Flink的开发记录,我把之前的单条操作换成批量了,批量SQL的考虑多了很多,我会详细介绍的,从Java定时器,flink定时器,时间窗口三种方案中如何抉择,填坑啥的。我会继续努力的,对了,我弄了个个人网站,欢迎来看喔,目前是草创阶段,会放一些我过往的文章进去,后续会增加一些除了文章之外的东西进去,大家都想看啥呢,有啥想法呢,评论回复一下喔,谢啦!云上之城-我的个人小站
转载自:https://juejin.cn/post/7271907645166288907