先展示一个 document 数据结构
GET /product/_doc/1
{
“_index” : “product”,
“_type” : “_doc”,
“_id” : “1”,
“_version” : 1,
“_seq_no” : 0,
“_primary_term” : 1,
“found” : true,
“_source” : {
“name” : “gaolujie yagao”,
“desc” : “gaoxiao meibai”,
“price” : 30,
“producer” : “gaolujie producer”,
“tags” : [
“meibai”,
“fangzhu”
]
}
}
下面我们就来开始分析了
1、document 的核心元数据
(1)_index 元数据
1、_index 代表一个 document 存放在哪个 index 中 2、对于 document,类似的数据都是放在一个索引里面的,,非类似的数据放在不同的索引中。例如,product_index 是包含了所有商品的 index,sales_index 是包含了所有商品的销售数据的 index,inventory_index 是包含了所有库存相关的数据。如果想把所有的这些数据都放在一个索引中, 比如创建一个 company_index,是不合适的。3、对于每个索引一般都是包含了很多类似的 document,类似是什么意思,其实指的就是说,这些 document 的 fields 很大一部分是相同的,如果说你放了三个 document, 但是每个 document 的 fields 都完全不一样,这就不是类似了,就不太适合放到一个 index 里面去了。4、对于语法,要求每个索引名称必须是小写的,不能用下划线开头,不能包含逗号。
(2)_type 元数据
1、_type 代表这个 document 属于 index 中的哪个类别(type)2、一个索引只能有一个 type,在后面的 ES 高版本中可能会废弃掉 3、对于 type 的语法,它可以是大写或是小写,但是同时不能用下划线开头,不能包含逗号
(3)_id 元数据
1、_id 代表 document 的唯一标识,与 index 和 type 一起,可以唯一标识和定位一个 document2、我们可以手动指定 document 的 id,也可以不指定,那 ES 就会自动为我们创建一个 id
下面附上中华石衫老师的手工图,说明一下为什么不同类型的数据不用一个索引存放
归纳一下就是如果把多个不同类型的数据放在一个索引中存储,当用户查询某一类的数据的时候比如商品数据,大量的请求过来,发现此时后台数据分析系统对这个索引下的另一类数据在做聚合分析比如销售数据,此时这些 shard 正在执行非常耗时,耗费资源的大型的聚合分析操作。就会导致 document get 请求,大量的性能不好,甚至超时。让用户感觉上来说,网速好慢,影响用户体验。
2、document id 的生成
(1)手动指定 document id
1、手动指定 document id 时,需要看下是否满足前提条件:一般来说,是从某些其他的系统中,导入一些数据到 es 时,会采取这种方式,就是使用系统中已有数据的唯一标识,作为 es 中的 document id。举个例子,假如我们现在在开发一个电商网站,做搜索功能,或者是 OA 系统,做员工的检索功能。这个时候数据首先会在网站系统或者 IT 系统内部的数据库中,会先有一份,此时肯定就会有一个数据库的 primary id(自增长,UUID,或者是业务编号) 如果将数据导入到 ES 中,此时就比较适合采用数据在数据库中的已有 primary key。2、格式
PUT /{index}/{type}/{id}
(2)自动生成 document id
在什么情况下使用自动的 document id。对于日志的搜集使用自动的 document id 是比较适合的。还有就是比如我们是在做一个系统,这个系统主要的数据存储就是 es 一种,也就是说,数据产生出来以后,可能就没有 id,直接就放 ES 存储,那么这个时候,可能就不太适合说手动指定 document id 的形式了。格式:
POST /{index}/{type}
注:自动生成的 id,长度为 20 个字符,URL 安全,base64 编码,GUID, 分布式系统并行生成时不可能会发生冲突
3、_source 元数据以及定制返回结果
(1)_source 元数据先用一个例子引出一个 document 的_source,以及它的结构
GET /product/_doc/1
{
“_index” : “product”,
“_type” : “_doc”,
“_id” : “1”,
“_version” : 1,
“_seq_no” : 0,
“_primary_term” : 1,
“found” : true,
“_source” : {
“name” : “gaolujie yagao”,
“desc” : “gaoxiao meibai”,
“price” : 30,
“producer” : “gaolujie producer”,
“tags” : [
“meibai”,
“fangzhu”
]
}
}
可以看出_source 元数据就是说,我们在创建一个 document 的时候,使用的那个放在 request body 请求体中的 json 串。(2)定制返回结果指定_source 参数返回哪些 field 即可
GET /product/_doc/1?_source=name,desc,tags
{
“_index” : “product”,
“_type” : “_doc”,
“_id” : “1”,
“_version” : 1,
“_seq_no” : 0,
“_primary_term” : 1,
“found” : true,
“_source” : {
“name” : “gaolujie yagao”,
“desc” : “gaoxiao meibai”,
“tags” : [
“meibai”,
“fangzhu”
]
}
}
4、document 的全量替换、强制创建以及 lazy delete 机制
(1)document 的全量替换
1、全量替换的语法和创建文档是一样的,如果 document id 不存在,那么就是创建;如果 document id 已经存在,那么就是全量替换操作,替换 document 的 json 串内容 2、document 是不可变的,如果要修改 document 的内容,第一种方式就是全量替换,直接对 document 重新建立索引,替换里面所有的内容 3、ES 会将老的 document 标记为 deleted,然后新增我们给定的一个 document,当我们创建越来越多的 document 的时候,es 会在适当的时机在后台自动删除标记为 deleted 的 document
(2)document 强制创建
创建文档和全量替换的语法是一样的,但是有时我们想新建文档,不想替换文档格式:
PUT /{index}/{type}/{id}?op_type=create
(3)document 的删除
格式:
DELETE /{index}/{type}/{id}
注意删除并不是物理删除,只是会将文档标记为 deleted,当数据越来越多的时候,会在后台自动删除