集群内的原理

空集群

https://www.elastic.co/guide/cn/elasticsearch/guide/current/_an-empty-cluster.html

  1. ElastiSearch天生就是 分布式的 , 其强大之处在于水平扩容(增加节点)。
  2. 一个ElasticSearch实例就是一个节点,一个节点就是一个集群(只不过是空集群)。
  3. 拥有相同cluster.name的节点,组成一个集群,共同抗压。
  4. 选举主节点,主节点管理集群级别变更,增加删除节点、增加删除索引。从节点管理文档级别的操作
  5. 每个节点都知道所有文档的存储位置,请求发送到任何节点都ok。

索引

索引是保存数

据的地方,是指向1或N个具体分片的逻辑命名空间(类似mysql schema)。

索引名必须小写,不能以下划线开头,不能包含逗号。

分片

  1. 一个分片存储一部分数据。
  2. 一个分片就是一个lucence实例。
  3. 分片被分配到集群的各个节点里。
  4. 扩容缩容会移动分片,故不影响数据查询。
  5. 一个分片可以是  分片或者 副本 分片。
  6. 缺失主分片的索引无法正常工作。

创建索引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实例,其独占资源更多,故效率更高。
  • 节点数量扩容,总结点数大于主分片+副本分片数,可以运行中调整索引副本数,副本越多,检索效率也越高。
  • 节点数量不变,盲目增加分片数,会降低效率。

应对故障(运维类)

  1. 某节点宕机,其上某索引的部分主分片丢失,该索引无法正常工作,此时集群状态为红色(存在主分片无法正常工作则红)。
  2. 从新选举主节点,提升副本分片为主分片,副本分片减少,此时集群状态为黄色(部分副本分片丢失或异常)。
  3. 等节点重启,集群尝试恢复,恢复成功后,集群状态回归绿色。

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"}}

定义查询模板

  1. 使用_scripts端点将模板存储在集群状态中
  2. 在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的特点)

  1. document同时包含key:value。
  2. document可以嵌套包含另一个文档。
  3. document没有固定的字段,可以动态新增或忽略字段。

字段的特点(fields的特点)

es会特别关注并存储每个field的类型,这个类型被称为映射类型。

未归类

一个集群至少一个节点,一个节点是一个es进程。

节点可以有多个默认索引,创建新索引(库)默认产生10个分片,5个主分片(primary shard)5个副本分片(replica shard)。

一个es索引代表一个es的库,库里面包含多个lucense索引文件,每个文件包含<标签,含有标签的document>

一定要保证es的maven相关包和当前使用的es版本保持一致。

集群的健康状况为 yellow 则表示全部  分片都正常运行(集群可以正常服务所有请求),但是 副本分片没有全部处在正常状态。

ElasticSearch7 学习笔记相关推荐

  1. Elasticsearch7学习笔记(中)

    Elasticsearch是实时全文搜索和分析引擎,提供搜集.分析.存储数据三大功能:是一套开放REST和JAVA API等结构提供高效搜索功能,可扩展的分布式系统.它构建于Apache Lucene ...

  2. ElasticSearch7学习笔记之Mapping

    文章目录 背景 倒排索引 定义 核心组成 ES中的数据类型 DynamicMapping 能否更改Mapping的字段类型 dynamic为false dynamic为strict 自定义Mappin ...

  3. Elasticsearch7学习笔记(尚硅谷)

    文章目录 一.ElasticSearch概述 1.ElasticSearch是什么 2.全文搜索引擎 3.ElasticSearch 和 Solr 3.1 概述 3.2 比较总结 二.Elastics ...

  4. Elasticsearch8.x学习笔记

    文章目录 一.Elasticsearch8.x概述 1.Elasticsearch 新特性 2.8.x与7.x的对比 二.Elasticsearch **安装**与使用 1.Elasticsearch ...

  5. ElasticSearch7.6.x 学习笔记

    ElasticSearch7.6.x 学习笔记 目录 ElasticSearch概述 ElasticSearch,简称es,es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储.检索数据. ...

  6. 【ElasticSearch7.X】学习笔记(一)

    [ElasticSearch7.X]学习笔记 一.介绍 1.1.ElasticSearch 1.2.RESTful 1.3.数据格式 二.下载安装(单机部署) 2.1.解压文件 2.2.修改配置配置 ...

  7. 【ElasticSearch7.X】学习笔记(三)

    [ElasticSearch7.X]学习笔记 五.集群部署 5.1.相关概念 5.1.1.集群 Cluster 3.1.2.节点 Node 5.2.下载安装 5.3. 启动 5.4. 测试 六.进阶 ...

  8. Elasticsearch-7.x学习笔记

    本文转载自:阅读原文 文章目录 1. 单节点安装 2. ES安装head插件 3. Elasticsearch Rest基本操作 REST介绍 CURL创建索引库 查询索引-GET DSL查询 MGE ...

  9. Elasticsearch7.17学习笔记

    前言 本学习笔记主要基于 阅读Elasticsearch7.17版本官方文档和实操总结而来,官方文档地址https://www.elastic.co/guide/en/elasticsearch/re ...

最新文章

  1. oracle 更新丢失
  2. python编程小学生学好吗-小学生都开始学的Python编程到底是什么?
  3. 关于Django中,实现序列化的几种不同方法
  4. 手机轮廓光怎么拍_摄影技巧:怎么拍影子?手机拍照教程
  5. Hadoop核心组件以及发行版
  6. CSDN博主排名更新公告
  7. 均线带角度的指标_指标:均线斜率角度计算
  8. 计算矩阵中全1子矩阵的个数
  9. 列表应用(导航菜单)
  10. monkey测试小记
  11. zynq pl 发数据给 ps
  12. css鼠标hover的时候变成小手型
  13. 为什么拼多多推广出价没人点击?新店铺怎么推广?
  14. 华硕fl5600l重装系统
  15. 备份win10的驱动程序
  16. 2021Java不死我不倒,吊打面试官系列!
  17. 女巫攻击Sybil Attack 笔记
  18. 【Android SDM660源码分析】- 01 - 如何创建 UEFI XBL Protocol DXE_DRIVER 驱动及UEFI_APPLICATION 应用程序
  19. 微信开发者工具更换默认用户存储目录(User Data)方法
  20. 数据库实验(二二二)

热门文章

  1. 西米支付:游戏支付平台,游戏支付接口申请相关知识及流程,需要申请的坛友可参考
  2. QT播放Wav音频并显示波形
  3. 用Spock测试AKKA应用程序
  4. wade12138 的Zcash-sapling分享
  5. c++扫雷以及自动扫雷ai性能测试
  6. html2canvas文字重叠
  7. 关于 AMP Story,你需要知道这些
  8. Eclipse中如何创建maven web工程
  9. cube 设置滴答定时器_CubeMX配置定时器产生指定个数的脉冲
  10. JetSonNano入门和人脸识别