在这篇文章中,我们将为您详细介绍第16篇:Elasticsearch文档元数据信息的内容,并且讨论关于elasticsearch元数据的相关问题。此外,我们还会涉及一些关于appsync使用elast
在这篇文章中,我们将为您详细介绍第16篇:Elasticsearch文档元数据信息的内容,并且讨论关于elasticsearch 元数据的相关问题。此外,我们还会涉及一些关于appsync 使用 elasticsearch 作为数据源:Elasticsearch 响应错误:禁止、Elasticsearch 2.20 文档篇:多文档操作、Elasticsearch 2.20 文档篇:新增文档、Elasticsearch 2.20 文档篇:更新删除文档的知识,以帮助您更全面地了解这个主题。
本文目录一览:- 第16篇:Elasticsearch文档元数据信息(elasticsearch 元数据)
- appsync 使用 elasticsearch 作为数据源:Elasticsearch 响应错误:禁止
- Elasticsearch 2.20 文档篇:多文档操作
- Elasticsearch 2.20 文档篇:新增文档
- Elasticsearch 2.20 文档篇:更新删除文档
第16篇:Elasticsearch文档元数据信息(elasticsearch 元数据)
背景:目前国内有大量的公司都在使用 Elasticsearch,包括阿里、京东、滴滴、今日头条、小米、vivo等诸多知名公司。除了搜索功能之外,Elasticsearch还结合Kibana、Logstash、Elastic Stack还被广泛运用在大数据近实时分析领域,包括日志分析、指标监控等多个领域。
本节内容:Elasticsearch文档元数据。
目录
1、文档索引 _index
2、文档类型 _type
3、文档主键 _id
4、其他元数据
4.1 版本 _version
4.2 顺序号 _seq_no
4.3 Primary编号 _primary_term
4.4 执行结果状态 found
4.5 数据源 _source
我们知道,一个文档中,不仅仅包含它的业务数据 ,也包含有关文档的元数据信息。 一个文档必须有以下3个元数据。
_index:文档存放的位置,相当于关系型数据库MysqL的db_name。
_type:文档表示的对象类别,相当于关系型数据库MysqL的表,不过在ES 7.x之后统一为_doc了。
_id:文档唯一标识,类似于关系型数据库MysqL的主键。
1、文档索引 _index
一个索引应该是因共同的特性被分组到一起的文档集合。 例如,你可能存储所有的学生在索引 student 中,而存储所有的学生成绩到索引 student_score 中。 虽然也允许存储不相关的数据到一个索引中,但这通常看作是一个反模式的做法。
实际上,在 Elasticsearch 中,我们的数据是被存储和索引在分片中,而一个索引仅仅是逻辑上的命名空间, 这个命名空间由一个或者多个分片组合在一起。 然而,这是一个内部细节,我们的应用程序根本不应该关心分片,对于应用程序而言,只需知道文档位于一个索引内。 Elasticsearch 会处理所有的细节。
Elasticsearch 创建索引名,这个名字必须小写,不能以下划线开头,不能包含逗号。
仅限小写字母
不能包含、/、 *、?、"、<、>、|、#以及空格符等特殊符号
从7.0版本开始不再包含冒号
不能以-、_或+开头
不能超过255个字节
例如,创建一个学生成绩索引。
POST http://localhost:9200/student_score
# student_score 为索引名
{
"settings": {
"index": {
"number_of_shards": 5,"number_of_replicas": 3
}
}
}
2、文档类型 _type
数据可能在索引中只是松散的组合在一起,但是通常明确定义一些数据中的子分区是很有用的。 例如,所有的学生都放在一个索引中,但是你有许多不同年级的学生,比如 "grade one" 、 和 "grade two"。
这些文档共享一种相同的(或非常相似)的模式:他们有共同的姓名、成绩和课程。他们只是正好属于“不同年级”下的一些子类。
Elasticsearch 公开了一个称为 types类型的特性,它允许您在索引中对数据进行逻辑分区。不同 types 的文档可能有不同的字段,但最好能够非常相似。
_type规范:
一个 _type 命名可以是大写或者小写,但是不能以下划线或者句号开头,不应该包含逗号, 并且长度限制为256个字符。
{
"settings": {
"index": {
"number_of_shards": 5,"number_of_replicas": 3
}
},"mappings": {
"score": { // _type,在7.x之后,默认为_doc
"_source": {
"enabled": false
},"properties": {
"name": {
"type": "string"
},"score": {
"type": "integer"
}
}
}
}
}
3、文档主键 _id
ID 是一个字符串,当它和 _index 以及 _type 组合就可以唯一确定 Elasticsearch 中的一个文档。 当你创建一个新的文档,要么提供自己的 _id ,要么让 Elasticsearch 帮你生成。
自定义格式:
http://localhost:9203/index/_doc/id #id可以自己指定
例如,http://localhost:9203/student/_doc/100
Elasticsearch 自动生成:
4、其他元数据
4.1 版本 _version
主要为了解决数据冲突问题。
ElasticSearch采用乐观并发控制。Elasticsearch是分布式的,当文档被创建、更新或删除,文档的新版本会被复制到集群的其它节点。Elasticsearch即是同步的又是异步的,意思是这些复制请求都是平行发送的,并无序(out of sequence)的到达目的地。这就需要一种方法确保老版本的文档永远不会覆盖新的版本。
版本规则:
每个文档都有一个_version编号,这个编号在文档被改变时加1,Elasticsearch使用这个_version保证所有修改都被正确排序。当一个旧版本出现在新版本之后,它会被简单的忽略。
{
"_index": "student","_type": "_doc","_id": "100","_version": 1,//版本号
"_seq_no": 20,"_primary_term": 1,"found": true,"_source": {
"name": "xiaoli","age": 18,"love": "I like swimming.","createTime": "2022-05-04 20:00:00"
}
}
4.2 顺序号 _seq_no
_seq_no是严格递增的顺序号,每个文档一个,Shard级别严格递增,保证后写入的Doc的_seq_no大于先写入的Doc的_seq_no。任何类型的写操作,包括index、create、update和Delete,都会生成一个_seq_no。
{
"_index": "student","_seq_no": 20,//顺序号
"_primary_term": 1,"createTime": "2022-05-04 20:00:00"
}
}
4.3 Primary编号 _primary_term
_primary_term主要是用来恢复数据时处理当多个文档的_seq_no一样时的冲突,比如当一个shard宕机了,raplica需要用到最新的数据,就会根据_primary_term和_seq_no这两个值来拿到最新的document
_primary_term:_primary_term也和_seq_no一样是一个整数,每当Primary Shard发生重新分配时,比如重启,Primary选举等,_primary_term会递增1
4.4 执行结果状态 found
found表示执行最中结果成功与否。
4.5 数据源 _source
Elasticsearch中有一个重要的概念是source,存储原始文档,也可以通过过滤设置只存储特定Field。
appsync 使用 elasticsearch 作为数据源:Elasticsearch 响应错误:禁止
我已经为同样的问题苦苦挣扎了几天。 就我而言,问题是自动生成的 IAM 角色被授予 ES 端点的权限,并且通过更改对整个 ES 域的“资源”引用来解决。例如:
之前:
"Resource": [
"arn:aws:es:us-east-1:11111:domain/search-foo-bar-search-someid123.us-east-1.es.amazonaws.com"
]
之后:
"Resource": [
"arn:aws:es:us-east-1:11111:domain/foo-bar-search/*"
]
Elasticsearch 2.20 文档篇:多文档操作
在 Elasticsearch 对文档的操作中,之前介绍的都是对单个文档进行操作,其实 Elasticsearch 同时可以对多个文档同时操作。下面介绍多文档查询。
多文档查询
多文档查询可以在同一个接口中查询多个文档,可以分别指定 index,type,id 来进行多个文档的查询,响应包括所有查询到文档数组,每个元素在结构上类似于单个文档查询,例如:
请求:POST http://localhost:9200/_mget?pretty
参数:
{
"docs" : [
{
"_index" : "secilog",
"_type" : "log",
"_id" : "1"
},
{
"_index" : "secilog",
"_type" : "log",
"_id" : "2"
}
]
}
返回结果:
{
"docs" : [ {
"_index" : "secilog",
"_type" : "log",
"_id" : "1",
"_version" : 3,
"found" : true,
"_source" : {
"collect_type" : "syslog",
"collect_date" : "2016-01-11T09:32:12",
"message" : "Failed password for root from 192.168.21.2 port 50790 ssh2"
}
}, {
"_index" : "secilog",
"_type" : "log",
"_id" : "2",
"_version" : 1,
"found" : true,
"_source" : {
"collect_type" : "syslog",
"collect_date" : "2016-01-12T09:32:12",
"message" : "secisland mget test!"
}
} ]
}
从中可以看出,一次查询了两个文档。
在查询的时候,index,type 可以在 url 中直接填写。例如下面两个请求和之前的是等价的。
请求:POST http://localhost:9200/secilog/_mget?pretty
参数:
{
"docs" : [
{
"_type" : "log",
"_id" : "1"
},
{
"_type" : "log",
"_id" : "2"
}
]
}
请求:POST http://localhost:9200/secilog/log/_mget?pretty
参数:
{
"docs" : [
{
"_id" : "1"
},
{
"_id" : "2"
}
]
}
对于上一种,可以用更加简化的方式查询:
请求:POST http://localhost:9200/secilog/log/_mget?pretty
参数:
{
"ids" : ["1","2" ]
}
从上面的例子可以看出,Elasticsearch 的多文档查询还是很灵活的。
type 参数说明
在多文档查询中,_type 允许为空,当他设置为空或者_all 的时候,系统会匹配第一个查询到的结果。如果不设置_type,当有许多文件有相同的_id 的时候,系统最终得到的只有第一个匹配的文档。例如:
请求:POST http://localhost:9200/secilog/_mget?pretty
参数:
{
"ids" : ["1","2" ]
}
上面的查询当有多个 type 中都有 1,2id 的时候,系统只会返回第一个找到的文档。如果想要多个,就需要把 type 在请求参数中指出来。
默认情况下,_source 字段将在每个文件中返回(如果存储)。类似单个文档的查询,可以在 url 中指定_source, _source_include 或者_source_exclude 来对查询的结果进行过滤。例如:
请求:POST http://localhost:9200/secilog/log/_mget?pretty
参数:
{
"docs" : [
{
"_id" : "1",
"_source" : false
},
{
"_id" : "2",
"_source" : ["collect_type", "collect_date"]
}
]
}
返回结果:
{
"docs" : [ {
"_index" : "secilog",
"_type" : "log",
"_id" : "1",
"_version" : 3,
"found" : true
}, {
"_index" : "secilog",
"_type" : "log",
"_id" : "2",
"_version" : 1,
"found" : true,
"_source" : {
"collect_date" : "2016-01-12T09:32:12",
"collect_type" : "syslog"
}
} ]
}
类似单个文档查询,在请求的 url 中或者参数的 docs 中可以指定 field,routing 参数。
块操作
快操作可以在一个接口中,处理个文档的内容,包括创建文档,删除文档,和修改文档。用块操作方式操作多个文档可以提高系统的效率。例如:
请求:POST http://localhost:9200/_bulk?pretty
参数:
{ "index" : { "_index" : "test", "_type" : "type1", "_id" : "10" } }
{ "field1" : "value1" }
{ "index" : { "_index" : "test", "_type" : "type1", "_id" : "13" } }
{ "field1" : "value3" }
{ "delete" : { "_index" : "test", "_type" : "type1", "_id" : "12" } }
}
返回结果:
{
"took" : 1,
"errors" : false,
"items" : [ {
"index" : {
"_index" : "test",
"_type" : "type1",
"_id" : "10",
"_version" : 6,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"status" : 200
}
}, {
"index" : {
"_index" : "test",
"_type" : "type1",
"_id" : "13",
"_version" : 1,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"status" : 201
}
}, {
"delete" : {
"_index" : "test",
"_type" : "type1",
"_id" : "12",
"_version" : 2,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"status" : 404,
"found" : false
}
} ]
}
和批量查询类似, /_bulk, /{index}/_bulk, and {index}/{type}/_bulk 这三种方式都可以执行,只需要在请求的参数中做出相应的对应。
赛克蓝德 (secisland) 后续会逐步对 Elasticsearch 的最新版本的各项功能进行分析,近请期待。也欢迎加入 secisland 公众号进行关注。
Elasticsearch 2.20 文档篇:新增文档
新增文档
新增文档是把一条新的文档增加到索引中,使之能够进行搜索,文档的格式是 JSON 格式。 注意:在 Elasticsearch 中如果文档的 id 存在,则更新此文档。例如我们在索引 secilog 中下面增加一条文档:
请求:PUT http://localhost:9200/secilog/log/1
参数:
{
"collect_type" : "syslog",
"collect_date" : "2016-01-11T09:32:12",
"message" : "Failed password for root from 192.168.21.1 port 50790 ssh2"
}
返回结果:
{
"_index": "secilog",
"_type": "log",
"_id": "1",
"_version": 1,
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": true
}
返回结果中的_shards 说明,_shards 提供了索引创建的过程信息:
total: 文档被创建的时候,在多少个分片中进行了操作,包括主分片和副本分片;
successful:成功建立索引分片的数量,当创建成功后,成功创建索引分片的数量最少是 1;
failed: 失败建立索引分片的数量。
自动创建索引
当创建文档的时候,如果索引不存在,则会自动创建该索引。自动创建的索引会自动映射每个字段的类型。自动创建字段类型是非常灵活的,新的字段类型将会自动匹配字段对象的类型。比如字符串类型,日期类型。自动创建索引可以通过配置文件设置 action.auto_create_index 为 false 在所有节点的配置文件中禁用。自动映射的字段类型可以通过配置文件设置 index.mapper.dynamic 为 false 禁用。自动创建索引可以通过模板设置索引名称,例如:可以设置 action.auto_create_index 为 +aaa*,-bbb*,+ccc*,-* (+ 表示准许,- 表示禁止)。
版本号
每个文档都有一个版本号,版本号的具体值放在在创建索引的返回值中 ("_version":)。通过版本号参数可以达到乐观并发控制的效果。当在操作文档的过程中指定版本号,如果和版本号不一致的时候操作会被拒绝。版本号常用在对事务的处理中。例如,更新刚才创建的文档:
请求:PUT http://localhost:9200/secilog/log/1?version=2&pretty
参数:
{
"message" : "elasticsearch now has versioning support!"
}
返回内容为更新失败:
{
"error" : {
"root_cause" : [ {
"type" : "version_conflict_engine_exception",
"reason" : "[log][1]: version conflict, current [-1], provided [2]",
"index" : "secilog",
"shard" : "2"
} ],
"type" : "version_conflict_engine_exception",
"reason" : "[log][1]: version conflict, current [-1], provided [2]",
"index" : "secilog",
"shard" : "2"
},
"status" : 409
}
注意:版本号是实时更新的,不会存在缓存现象。当操作的时候不指定版本号,则系统不会对版本号是否一致进行检查。
默认情况下对文档的操作版本号从 1 开始递增,包括修改文档和删除文档。当然版本号还可以从外部获取,比如从数据库中获取,要启用此功能,version_type 应设置为 external,这个值必须是一个大于 0 小于 9.2e+18 的数字。当使用外部版本号来代替自动生成的版本号时,在操作文档的时候,系统通过对比参数中的版本号是否大于文档中的版本号来做判断,当参数中的版本号大于系统中的版本号,则执行此操作,并更新版本号。反之则拒绝操作 (包括小于或者等于)。
版本号同时产生了一个比较实用的功能,只要版本号从源数据库中使用,在异步索引操作的时候就不需要对源数据库的变化执行严格排序。任何操作都只会对最新的版本号起作用,不管这个版本号是内部的还是从外部获取的。
本文由赛克蓝德 (secisland) 原创,转载请标明作者和出处。
操作类型
系统同时支持通过 op_type=create 参数强制命令只执行创建操作,只有系统中不存在此文档的时候才会创建成功。如果不指定此操作类型,如果存在此文档,则会更新此文档。例如再次创建文档:
请求:PUT http://localhost:9200/secilog/log/1?op_type=create&pretty
参数:
{
"collect_type" : "syslog",
"collect_date" : "2016-01-11T09:32:12",
"message" : "Failed password for root from 192.168.21.2 port 50790 ssh2"
}
返回值,表示创建失败:
{
"error" : {
"root_cause" : [ {
"type" : "document_already_exists_exception",
"reason" : "[log][1]: document already exists",
"index" : "secilog",
"shard" : "3"
} ],
"type" : "document_already_exists_exception",
"reason" : "[log][1]: document already exists",
"index" : "secilog",
"shard" : "3"
},
"status" : 409
}
当不指定 op_type=create 时候,则更新此文档。
创建操作的另一个写法为:http://localhost:9200/secilog/log/1/_create?pretty
自动创建 ID
当创建文档的时候,如果不指定 id,系统会自动创建 id。自动生成的 id 是一个不会重复的随机数。例如:
请求:POST http://localhost:9200/secilog/log/?op_type=create&pretty
参数:
{
"collect_type" : "syslog",
"collect_date" : "2016-01-11T09:32:12",
"message" : "Failed password for root from 192.168.21.2 port 50790 ssh2"
}
返回值:
{
"_index" : "secilog",
"_type" : "log",
"_id" : "AVLOV99W6rG7Qqt6i_gk",
"_version" : 1,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"created" : true
}
从中可以看出_id 自动生成了一个随机数。
分片选择
默认情况下,分片的选择是通过 ID 的散列值进行控制,分片的选择。这个只可以通过 router 参数进行手动的控制。可以在每个操作的基础上直接通过哈希函数的值来指定分片的选择。例如:
请求:POST http://localhost:9200/secilog/log/?routing=secisland&pretty
在上面的例子中,分片的选择是通过指定 routing=secisland 参数的哈希值来确定的。
其他说明
分布式:索引操作主要是针对主节点的分片进行,当主节点完成索引操作后,如果有副本节点,则分发到副本中。
一致性:为了防止当网络出现问题的时候写入不一致,系统只有在有效节点的数量大于一定数量的时候生效 (总结点数 / 2+1),该值可以通过 action.write_consistency 参数进行修改。
刷新:更新的时候可以指定 refresh 参数为 true 来立即刷新所有的副本,当 refresh 设置为 true 的时候,系统做了充分的优化,不会对系统产生任何影响,需要注意的是查询操作 refresh 参数没有任何的意义。
空操作:当文档内容没有任何改变的时候,更新文档操作也会生效,具体体现在版本号会发生变化。如果不希望此情况发生,在更新的时候指定 detect_noop 为 true。这个参数在创建索引的时候无效。
超时:默认情况下系统的超时时间是一分钟。可以通过设置 timeout 来修改超时的时间,例如 timeout=5m,表示超时的时间是 5 分钟。
赛克蓝德 (secisland) 后续会逐步对 Elasticsearch 的最新版本的各项功能进行分析,近请期待。也欢迎加入 secisland 公众号进行关注。
Elasticsearch 2.20 文档篇:更新删除文档
Elasticsearch 的更新文档 API 准许通过脚本操作来更新文档。更新操作从索引中获取文档,执行脚本,然后获得返回结果。它使用版本号来控制文档获取或者重建索引。
备注:在 Elasticsearch 中的更新操作是完全从新索引文件。
我们新建一个文档:
请求:PUT http://localhost:9200/test/type1/1?pretty
参数:
{
"counter" : 1,
"tags" : ["red"]
}
脚本开启功能
在最新版本的 Elasticsearch 中,基于安全考虑 (如果用不到,请保持禁用), 默认禁用了动态脚本功能。如果被禁用,在使用脚本的时候则报以下的错误:
scripts of
type
[inline], operation [update] and lang [groovy] are disabled
可以用以下方式完全开启动态脚本功能,在 config/elasticsearch.yml 文件,在最后添加以下代码:
script.inline: on
script.indexed: on
script.file: on
配置后,重启 Elasticsearch。
下面我们用脚本来更新此文档。
请求:POST http://localhost:9200/test/type1/1/_update?pretty
参数:
{
"script" : {
"inline": "ctx._source.counter += count",
"params" : {
"count" : 4
}
}
}
执行完后,我们在查询一下文档内容,可以发现 counter 的值为 5:
{
"_index" : "test",
"_type" : "type1",
"_id" : "1",
"_version" : 5,
"found" : true,
"_source" : {
"counter" : 5,
"tags" : [ "red" ]
}
}
在看下面的更新操作:
请求:POST http://localhost:9200/test/type1/1/_update?pretty
参数:
{
"script" : {
"inline": "ctx._source.tags += tag",
"params" : {
"tag" : "blue"
}
}
}
返回的内容为,表示更新成功,我们看一下_version 为 6,比刚才的值增加了 1:
{
"_index" : "test",
"_type" : "type1",
"_id" : "1",
"_version" : 6,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
}
}
然后我们在查询一下文档内容:
{
"_index" : "test",
"_type" : "type1",
"_id" : "1",
"_version" : 6,
"found" : true,
"_source" : {
"counter" : 5,
"tags" : [ "red", "blue" ]
}
}
在脚本中除了_source 外其他内置参数也可以使用,例如_index, _type, _id, _version, _routing, _parent, _timestamp, _ttl。
下面我们通过脚本增加一列。
请求:POST http://localhost:9200/test/type1/1/_update?pretty
参数:
{
"script" : "ctx._source.name_of_new_field = \"value_of_new_field\""
}
然后查询此文档:
{
"_index" : "test",
"_type" : "type1",
"_id" : "1",
"_version" : 7,
"found" : true,
"_source" : {
"counter" : 5,
"tags" : [ "red", "blue" ],
"name_of_new_field" : "value_of_new_field"
}
}
从中可以看出,文档中又增加了一列。
删除一列,请求和刚才的一样,参数变为:
{
"script" : "ctx._source.remove(\"name_of_new_field\")"
}
甚至可以通过表达式来判断做某些事情,例如:下面的示例将删除的文件如果标签字段包含蓝色,否则什么也不做(空):
请求参数:
{
"script" : {
"inline": "ctx._source.tags.contains(tag) ? ctx.op = \"delete\" : ctx.op = \"none\"",
"params" : {
"tag" : "blue"
}
}
}
部分文档更新:
该更新接口还支持更新部分文档,将文档合并到现有文档中(简单的递归合并、对象的内部合并、替换核心的 “键 / 值” 和数组)。例如:
{
"doc" : {
"name" : "new_name"
}
}
更新后,可以发现文档中多了一列 name。
{
"_index" : "test",
"_type" : "type1",
"_id" : "1",
"_version" : 23,
"found" : true,
"_source" : {
"counter" : 5,
"tags" : [ "red", "blue" ],
"name" : "new_name"
}
}
当文档指定的值与现有的_source 合并。当新的文档和老的文档不一致的时候,文档将会被从新建立索引。当新旧文档一样的时候,则不进行从建索引的操作。可以通过设置 detect_noop 为 false,让任何情况下都从新建立索引,例如下面的更新操作:
{
"doc" : {
"name" : "new_name"
},
"detect_noop": false
}
删除文档
删除文档相对比较简单:
请求:DELETE http://localhost:9200/test/type1/1
返回的内容为:
{
"found": true,
"_index": "test",
"_type": "type1",
"_id": "1",
"_version": 24,
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
}}
则表示删除了此文档。
赛克蓝德 (secisland) 后续会逐步对 Elasticsearch 的最新版本的各项功能进行分析,近请期待。也欢迎加入 secisland 公众号进行关注。
我们今天的关于第16篇:Elasticsearch文档元数据信息和elasticsearch 元数据的分享就到这里,谢谢您的阅读,如果想了解更多关于appsync 使用 elasticsearch 作为数据源:Elasticsearch 响应错误:禁止、Elasticsearch 2.20 文档篇:多文档操作、Elasticsearch 2.20 文档篇:新增文档、Elasticsearch 2.20 文档篇:更新删除文档的相关信息,可以在本站进行搜索。
本文标签: