Elasticsearch-9-document核心元数据解析

本文主要写document中的_index,_type,_id,_source这几个元数据
先随便添加一个document

1
2
3
4
PUT /test_index/test_type/1
{
"test_content":"test content"
}

查询

1
GET  /test_index/test_type/1

返回值

1
2
3
4
5
6
7
8
9
10
{
"_index": "test_index",
"_type": "test_type",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"test_content": "test content"
}
}

返回值详解

_index元数据
  1. 代表document存放在哪一个index中
  2. 类似的数据放在一个索引中,非类似的数据应该放到不同的索引中,什么意思呢,比如现在有一个商品类的数据(product)和一个商品销售的数据(sale),那么应该把product的数据放到一个index里面,sale的数据放到另一个index里面, 如果把所有的数据都放到一个index里面,这样做是不合适的.
  3. index中包含了很多类似的document,类似就是指这些document的fields很大一部分是相同的, 比如说现在有3个document但是每个document里面的fields是完全不一样的,这就是不类似的,就不太适合放到同一个index里面了
  4. 索引的命名规则,必须是小写的 不能用大写,第二 不能用下划线开头,第三 不能包含逗号

详细来说一下上面的第2点,为什么说应该把类似的数据放到同一个index里面, 比如我们现在把product的数据和sale的数据都放到了同一个index下, 这些数据将会被分配到不同的shard上面,每个shard上面既有product数据也有sale数据, 现在网站后台需要做sale的聚合分析,而且sale的数据量很大,这个时候所有的shard都会去执行这次聚合分析,耗费大量的资源,与此同时在网站前端用户需要去搜索product中的数据,因为这些shard都在做后台的聚合分析占用了大量的资源,导致前端用户搜索product数据时会变慢,影响用户体验,所以相同类型的数据放到一个index上,在自己独立的shard中与其他数据不在一个shard中就不会互相影响

_type元数据
  1. 代表document属于index中的哪个类别
  2. 一个索引通常会划分为多个type,逻辑上对index中有些许不同的数据进行分类,因为相同类型的数据,会有很多相同的fields,但是也可能有些许的差别,比如商品数据放到了一个index中,但是商品下面还划分为电子商品 生鲜商品 等等.
  3. type命名 名称是可以大小写的,但是不能用下划线开头也不能包含逗号
_id元数据
  1. 代表document的唯一标识,与index和type一起,可以定位一个document
  2. 我们可以手动指定document的id,也可以不指定 es会为我们自动创建一个id

Q:什么时候适合使用手动生成id,什么时候使用自动生成的id?
A:一般来说是从某些其他的系统中导入数据到es时,会采取这种方式,就是系统中已经有数据的唯一标识了,比如我们现在有一个商品的数据库,要把里面的数据导入到es里面做搜索,数据库里面肯定会有一个数据的主键primary key,这时将数据导入到es中的时候就适合用数据库中已有的primary key做id
自动生成的id,我们先来看一下,是什么样的
先添加一个数据,不指定id

1
2
3
4
POST /test_index/test_type
{
"test_content":"test1"
}

返回值:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"_index": "test_index",
"_type": "test_type",
"_id": "AWcctb8Zlcpuqacodv55",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": true
}

可以看到id是一个字符串,长度是固定为20位的,URL安全,base64编码,使用的是GUID生成策略,分布式系统并行生成时不可能发生冲突

_source元数据

就是我们在创建document的时候,在request中写入的json数据,当我们get的时候,会把这个json数据原封不动的返回到_source中来.
如果我们发送的有多个field 在返回时只想要指定的field 只需要在get请求后面加?_source=field1,field2…即可