ElasticSearch7 学习笔记
集群内的原理
空集群
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_an-empty-cluster.html
- ElastiSearch天生就是 分布式的 , 其强大之处在于水平扩容(增加节点)。
- 一个ElasticSearch实例就是一个节点,一个节点就是一个集群(只不过是空集群)。
- 拥有相同cluster.name的节点,组成一个集群,共同抗压。
- 选举主节点,主节点管理集群级别变更,增加删除节点、增加删除索引。从节点管理文档级别的操作。
- 每个节点都知道所有文档的存储位置,请求发送到任何节点都ok。
索引
索引是保存数
据的地方,是指向1或N个具体分片的逻辑命名空间(类似mysql schema)。
索引名必须小写,不能以下划线开头,不能包含逗号。
分片
- 一个分片存储一部分数据。
- 一个分片就是一个lucence实例。
- 分片被分配到集群的各个节点里。
- 扩容缩容会移动分片,故不影响数据查询。
- 一个分片可以是 主 分片或者 副本 分片。
- 缺失主分片的索引无法正常工作。
创建索引onionli,并指向3个主分片,且每个主分片一个副本分片,可见所有分片将会被分布在两个节点上。
PUT /onionli
{"settings" : {"number_of_shards" : 3,"number_of_replicas" : 1}
}
添加故障转移(运维类)
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_add_failover.html
水平扩容(运维类)
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_scale_horizontally.html
- 水平扩容后,每个节点的分片数更少,分片是Lucense实例,其独占资源更多,故效率更高。
- 节点数量扩容,总结点数大于主分片+副本分片数,可以运行中调整索引副本数,副本越多,检索效率也越高。
- 节点数量不变,盲目增加分片数,会降低效率。
应对故障(运维类)
- 某节点宕机,其上某索引的部分主分片丢失,该索引无法正常工作,此时集群状态为红色(存在主分片无法正常工作则红)。
- 从新选举主节点,提升副本分片为主分片,副本分片减少,此时集群状态为黄色(部分副本分片丢失或异常)。
- 等节点重启,集群尝试恢复,恢复成功后,集群状态回归绿色。
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_coping_with_failure.html
集群的健康
- green 健康
- yellow 主分片正常,部分副本分片异常
- red 存在主分片异常(某节点宕机,其上主分片丢失,缺失主分片的索引无法正常工作)
文档路由到分片
解释为何创建索引时要固定分片,文档会根据文档id进行hash后mod固定的分片数量,以确定文档位于哪个分片。所以若分片数变化,则之前分配好的文档就会都丢失了。
根据公式
shard = hash(routing) % number_of_primary_shards
所有的文档 API( get
、 index
、 delete
、 bulk
、 update
以及 mget
)都接受一个叫做 routing
的路由参数 ,通过这个参数我们可以自定义文档到分片的映射。一个自定义的路由参数可以用来确保所有相关的文档——例如所有属于同一个用户的文档——都被存储到同一个分片中。
索引相关
获取索引的映射(索引中会存储哪些字段,每个字段是啥类型,是什么格式)
GET /onion/_mapping
文档元数据
_index(文档归属索引)
- 索引是保存数据的地方,是指向1或N个具体分片的逻辑命名空间(类似mysql schema)。
- 索引名必须小写,不能以下划线开头,不能包含逗号。
_type(文档类型)
- 文档虽属于同一索引,但是可以继续细分类型,_type可以用于同索引下的文档进行二次逻辑分类。
_type
命名可以是大写或者小写,但是不能以下划线或者句号开头,不应该包含逗号, 并且长度限制为256个字符
_id
- ID 是一个字符串,当它和
_index
以及_type
组合就可以唯一确定 Elasticsearch 中的一个文档。 当你创建一个新的文档,要么提供自己的_id
,要么让 Elasticsearch 帮你生成。
对象指json,对象内部可嵌套对象。文档大部分等于对象,在存在嵌套时特指根对象。
插入文档
由于es7已经完全将type给废弃了,所以插入文档的语句中原本type的位置变为_doc或_create。
post /{index}/_doc/{id}
这种方式不论是否存在都能插入成功,不存在则纯插入,存在则更新文档和版本号。
post /{index}/_doc
这种方式系统会帮您自动创建id。
post /{index}/_create/{id}
这种方式会在插入前校验文档是否存在,存在则不插,不存在则插入,并会返回元数据和一个 201 Created
的 HTTP 响应码。
纯插
post /onion/_doc/id
{"name":"lisi","birth":"2021-05-20"
}
查询文档
简单查询
拿所有字段slect *
GET /onionli/typeA/id1?pretty pretty表示json化打印返回found=true{"_index": "onionli","_type": "typeA","_id": "id1","_version": 2,"_seq_no": 1,"_primary_term": 1,"found": true,"_source": {"name": "28","sex": 1}
}
拿部分字段select name,sex
先存入一个新文档
put /onionli/typeA/id2
{"name":"magic","sex":"0","age":10
}只查这个文档的name和sex两个字段
GET /onionli/typeA/id2?_source=name,sex
只拿业务数据(忽略文档元数据)
GET /onionli/typeA/id2/_source返回
{"name": "magic","sex": "0","age": 10
}
Query、Filter、Should、Must
https://blog.csdn.net/weixin_30446969/article/details/113491063
Query DSL 和 Filter DSL 的区别
先看案例,最外层是query,然后一个 bool 查询可以包含一个或多个查询字句 ,bool里面包含两部分:
- 查询部分 must、should、mustNot等,这部分被称为query DSL
- 过滤部分 filter,这部分被称为filter DSL
POST onion/_doc/_search
{"query": {"bool": {"must": [{"match_all": {}}],"filter": [{"term": {"name": {"value": "lisi"}}}]}}
}
Query DSL 和 Filter DSL的差别如下
Query DSL
- 会进行全文检索。
- 会进行相关性检查,比如查询包含run单词,如果包含这些单词:runs、running、jog、sprint,也被视为包含run单词。
- 查询结果不会被缓存。
- 查询结果会计算分值。
除非需要搜索文本,若纯粹当数据库使用,效率更低。
Filter DSL
- 仅仅校验field与传入的待匹配值是否相等。
- 结果会缓存。
- 查询结果不会贡献算分。
所以存粹当数据库使用,filter效率更高。
Query DSL 中的must、should、must not
- must:必须匹配,贡献算分
- should:选择性匹配,贡献算分
- must_not:查询字句,必须不能匹配
- filter:必须匹配,不贡献算分
上图是一个 bool 查询,是对用户(user)进行搜索,城市必须是北京(beijing) ,性别必须是男(man),这个采用的是 filter,说明这个对算分是不会产生影响的,must_not 是一个 range 的查询:年龄大于等于 35 岁;should 里是一个数组,说明这个 should 中可以写多个条件,只要用户的名字是这两个中的一个就是满足条件的。
其实,bool 查询的子查询可以任意顺序出现,并且可以嵌套多个查询。
另外,should 的使用分两种情况:
- bool 查询中只包含 should,不包含 must 或 filter 查询:如果在 bool 查询中没有 must、filter 子句,should 中必须至少满足一条查询(可以通过 minimum_should_match 来设置满足条件的个数或者百分比)。
- bool 查询中同时包含 should 和 (must或filter) 查询:同时包含 should 和 (must或filter) 时,文档不必满足 should 中的条件,但是如果满足条件,会增加相关性算分。
查询模板
官网 https://www.elastic.co/guide/en/elasticsearch/reference/7.x/search-template.html
https://www.cnblogs.com/sanduzxcvbnm/p/12085136.html
往es里存两份文档
PUT twitter/_doc/1{"user" : "双榆树-张三","message" : "今儿天气不错啊,出去转转去","uid" : 2,"age" : 20,"city" : "北京","province" : "北京","country" : "中国","address" : "中国北京市海淀区","location" : {"lat" : "39.970718","lon" : "116.325747"}}PUT twitter/_doc/2{"user" : "虹桥-老吴","message" : "好友来了都今天我生日,好友来了,什么 birthday happy 就成!","uid" : 7,"age" : 90,"city" : "上海","province" : "上海","country" : "中国","address" : "中国上海市闵行区","location" : {"lat" : "31.175927","lon" : "121.383328"}}
定义查询模板
- 使用
_scripts
端点将模板存储在集群状态中。 - 在search template中使用mustache语法。
{{#param1}}{{/param1} | 代表mybatis中的if标签,如果那个变量是false或null,则不会执行其中的片段。 |
{{#join}}array{{/join}} | 可以将数组转成逗号分隔的string |
{{#toJson}}parameter{{/toJson}} | 将map或array转成json格式 |
{"from": {{from}}{{^from}}0{{/from}},"size": {{size}}{{^size}}5{{/size}},"sort": [{"price_effective_time": "asc"}],"query": {"bool": {"filter": [{"exists": {"field": "mer_item_no"}}{{#startTime}},{"range": {"price_effective_time": {"gte": "{{startTime}}","format": "yyyy-MM-dd HH:mm:ss"}}}{{/startTime}}{{#endTime}},{"range": {"price_effective_time": {"lte": "{{endTime}}","format": "yyyy-MM-dd HH:mm:ss"}}}{{/endTime}}{{#midSet}},{"terms": {"merchandise_no": {{#toJson}}midSet{{/toJson}}} }{{/midSet}}{{#goodsNoSet}},{"terms": {"goods_no": {{#toJson}}goodsNoSet{{/toJson}}} }{{/goodsNoSet}}{{#merItemNoSet}},{"terms": {"mer_item_no": {{#toJson}}merItemNoSet{{/toJson}}} }{{/merItemNoSet}}{{#brandStoreSnSet}},{"terms": {"brand_store_sn": {{#toJson}}brandStoreSnSet{{/toJson}}} }{{/brandStoreSnSet}}]}}
}
使用模板查询
GET twitter/_search/template{"id": "my_search_template","params": {"my_field": "city","my_value": "北京"}}
获取查询模板
GET _scripts/<templateid>
删除查询模板
DELETE _scripts/<templateid>
调试查询模板(验证模板生成的DSL)
GET _search/template
{"id": "你的templateId","params": {"startTime":"2021-05-01 11:00:00","endTime":"2021-08-01 11:00:00","midSet":["1","2"],"goodsNoSet":["11","22"],"merItemNoSet":["111","222"],"brandStoreSnSet":["1111","2222"]}
}调试的渲染结果
{"from": 0,"size": 5,"sort": [{"price_effective_time": "asc"}],"query": {"bool": {"filter": [{"exists": {"field": "mer_item_no"}},{"range": {"price_effective_time": {"gte": "2021-05-01 11:00:00","format": "yyyy-MM-dd HH:mm:ss"}}},{"range": {"price_effective_time": {"lte": "2021-08-01 11:00:00","format": "yyyy-MM-dd HH:mm:ss"}}},{"terms": {"merchandise_no": ["1","2"]}},{"terms": {"merchandise_no": ["1","2"]}},{"terms": {"goods_no": ["11","22"]}},{"terms": {"goods_no": ["11","22"]}},{"terms": {"mer_item_no": ["111","222"]}},{"terms": {"mer_item_no": ["111","222"]}},{"terms": {"brand_store_sn": ["1111","2222"]}},{"terms": {"brand_store_sn": ["1111","2222"]}}]}}
}
删除文档
成功则返回200,找不到文档则返回404
DELETE /onionli/typeA/id1
批量删除
bulk批量删除(不是批量越大越好,上线前请先调优最佳批量大小)
https://www.elastic.co/guide/cn/elasticsearch/guide/current/bulk.html
批量处理
原文链接:https://blog.csdn.net/weixin_39723544/article/details/109237175
es中的批量处理就是使用bulk进行操作。
bulk的操作类型
- create 如果文档不存在就创建,但如果文档存在就返回错误
- index 如果文档不存在就创建,如果文档存在就更新
- update 更新一个文档,如果文档不存在就返回错误
- delete 删除一个文档,如果要删除的文档id不存在,就返回错误
- 其实可以看得出来index是比较常用的。还有bulk的操作,某一个操作失败,是不会影响其他文档的操作的,它会在返回结果中告诉你失败的详细的原因。
准备操作
- 测试数据准备
- 索引及映射结构准备
PUT example
PUT example/docs/_mapping
{"properties": {"id": {"type": "long"},"name": {"type": "text"},"counter": {"type": "integer"},"tags": {"type": "text"}}
}
批量插入
插入的action为index。
POST example/docs/_bulk
{"index": {"_id": 1}}
{"id":1, "name": "admin", "counter":"10", "tags":["red", "black"]}
{"index": {"_id": 2}}
{"id":2, "name": "张三", "counter":"20", "tags":["green", "purple"]}
{"index": {"_id": 3}}
{"id":3, "name": "李四", "counter":"30", "tags":["red", "blue"]}
{"index": {"_id": 4}}
{"id":4, "name": "tom", "counter":"40", "tags":["orange"]}
批量修改
修改的action为update。
POST example/docs/_bulk
{"update": {"_id": 1}}
{"doc": {"id":1, "name": "admin-02", "counter":"11"}}
{"update": {"_id": 2}}
{"script":{"lang":"painless","source":"ctx._source.counter += params.num","params": {"num":2}}}
{"update":{"_id": 3}}
{"doc": {"name": "test3333name", "counter": 999}}
{"update":{"_id": 4}}
{"doc": {"name": "test444name", "counter": 888}, "doc_as_upsert" : true}
批量删除
修改的action为delete。
POST example/docs/_bulk
{"delete": {"_id": 1}}
{"delete": {"_id": 2}}
{"delete": {"_id": 3}}
{"delete": {"_id": 4}}
批量的混合操作
不过一般不推荐这种使用,项目中也用的极少。
POST _bulk
{ "index" : { "_index" : "example", "_type" : "docs", "_id" : "1" } }
{ "name" : "value11111" }
{ "delete" : { "_index" : "example", "_type" : "docs", "_id" : "2" } }
{ "create" : { "_index" : "example", "_type" : "docs", "_id" : "3" } }
{ "tags" : "value333" }
{ "update" : {"_id" : "4", "_type" : "docs", "_index" : "example"} }
{ "doc" : {"name" : "混合444"}
并发控制(高级部分)
处理冲突
https://www.elastic.co/guide/cn/elasticsearch/guide/current/version-control.html
乐观并发控制
https://www.elastic.co/guide/cn/elasticsearch/guide/current/optimistic-concurrency-control.html
部分文档更新
https://www.elastic.co/guide/cn/elasticsearch/guide/current/partial-updates.html
更新文档
es提供了put 和 update两个api进行文档更新。
update较重,是从原文档生出新文档,再删除原文档,索引新文档。
https://www.elastic.co/guide/cn/elasticsearch/guide/current/update-doc.html
一切都是json
Mysql与es中名词的对应关系
- Index 对应 MySQL 中的 Database
- Type 对应 MySQL 中的 Table
- Document 对应 MySQL 中表的记录
- field对应MySQL中表的column
es在后台将每个索引划分成多个分片,分片可以在集群中不同服务器之间进行转移。
standalone模式的es,一个人就是一个集群,其集群名字默认为elasticSearch。
es文档的特点(Document的特点)
- document同时包含key:value。
- document可以嵌套包含另一个文档。
- document没有固定的字段,可以动态新增或忽略字段。
字段的特点(fields的特点)
es会特别关注并存储每个field的类型,这个类型被称为映射类型。
未归类
一个集群至少一个节点,一个节点是一个es进程。
节点可以有多个默认索引,创建新索引(库)默认产生10个分片,5个主分片(primary shard)5个副本分片(replica shard)。
一个es索引代表一个es的库,库里面包含多个lucense索引文件,每个文件包含<标签,含有标签的document>
一定要保证es的maven相关包和当前使用的es版本保持一致。
集群的健康状况为 yellow
则表示全部 主 分片都正常运行(集群可以正常服务所有请求),但是 副本分片没有全部处在正常状态。
ElasticSearch7 学习笔记相关推荐
- Elasticsearch7学习笔记(中)
Elasticsearch是实时全文搜索和分析引擎,提供搜集.分析.存储数据三大功能:是一套开放REST和JAVA API等结构提供高效搜索功能,可扩展的分布式系统.它构建于Apache Lucene ...
- ElasticSearch7学习笔记之Mapping
文章目录 背景 倒排索引 定义 核心组成 ES中的数据类型 DynamicMapping 能否更改Mapping的字段类型 dynamic为false dynamic为strict 自定义Mappin ...
- Elasticsearch7学习笔记(尚硅谷)
文章目录 一.ElasticSearch概述 1.ElasticSearch是什么 2.全文搜索引擎 3.ElasticSearch 和 Solr 3.1 概述 3.2 比较总结 二.Elastics ...
- Elasticsearch8.x学习笔记
文章目录 一.Elasticsearch8.x概述 1.Elasticsearch 新特性 2.8.x与7.x的对比 二.Elasticsearch **安装**与使用 1.Elasticsearch ...
- ElasticSearch7.6.x 学习笔记
ElasticSearch7.6.x 学习笔记 目录 ElasticSearch概述 ElasticSearch,简称es,es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储.检索数据. ...
- 【ElasticSearch7.X】学习笔记(一)
[ElasticSearch7.X]学习笔记 一.介绍 1.1.ElasticSearch 1.2.RESTful 1.3.数据格式 二.下载安装(单机部署) 2.1.解压文件 2.2.修改配置配置 ...
- 【ElasticSearch7.X】学习笔记(三)
[ElasticSearch7.X]学习笔记 五.集群部署 5.1.相关概念 5.1.1.集群 Cluster 3.1.2.节点 Node 5.2.下载安装 5.3. 启动 5.4. 测试 六.进阶 ...
- Elasticsearch-7.x学习笔记
本文转载自:阅读原文 文章目录 1. 单节点安装 2. ES安装head插件 3. Elasticsearch Rest基本操作 REST介绍 CURL创建索引库 查询索引-GET DSL查询 MGE ...
- Elasticsearch7.17学习笔记
前言 本学习笔记主要基于 阅读Elasticsearch7.17版本官方文档和实操总结而来,官方文档地址https://www.elastic.co/guide/en/elasticsearch/re ...
最新文章
- oracle 更新丢失
- python编程小学生学好吗-小学生都开始学的Python编程到底是什么?
- 关于Django中,实现序列化的几种不同方法
- 手机轮廓光怎么拍_摄影技巧:怎么拍影子?手机拍照教程
- Hadoop核心组件以及发行版
- CSDN博主排名更新公告
- 均线带角度的指标_指标:均线斜率角度计算
- 计算矩阵中全1子矩阵的个数
- 列表应用(导航菜单)
- monkey测试小记
- zynq pl 发数据给 ps
- css鼠标hover的时候变成小手型
- 为什么拼多多推广出价没人点击?新店铺怎么推广?
- 华硕fl5600l重装系统
- 备份win10的驱动程序
- 2021Java不死我不倒,吊打面试官系列!
- 女巫攻击Sybil Attack 笔记
- 【Android SDM660源码分析】- 01 - 如何创建 UEFI XBL Protocol DXE_DRIVER 驱动及UEFI_APPLICATION 应用程序
- 微信开发者工具更换默认用户存储目录(User Data)方法
- 数据库实验(二二二)