Elasticsearch-91-祖孙三层数据关系建模及搜索

数据建模

祖孙三层的数据建模

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PUT /company
{
"mappings": {
"country": {},
"rd_center": {
"_parent": {
"type": "country"
}
},
"employee": {
"_parent": {
"type": "rd_center"
}
}
}
}

看下请求,company下面有三个type,依次是country,rd_center,employee, 和之前一样,也是一层一层的指定parent就好了.

索引建好后,先在country里面添加几条数据

1
2
3
4
5
POST /company/country/_bulk
{ "index": { "_id": "1" }}
{ "name": "中国" }
{ "index": { "_id": "2" }}
{ "name": "美国" }

然后再添加研发中心的数据,和之前添加的方式是一样的,指定parent id就好了

1
2
3
4
5
6
7
POST /company/rd_center/_bulk
{ "index": { "_id": "1", "parent": "1" }}
{ "name": "北京研发总部" }
{ "index": { "_id": "2", "parent": "1" }}
{ "name": "上海研发中心" }
{ "index": { "_id": "3", "parent": "2" }}
{ "name": "硅谷人工智能实验室" }

最后,添加员工的数据

1
2
3
4
5
6
PUT /company/employee/1?parent=1&routing=1
{
"name": "张三",
"dob": "1970-10-24",
"hobby": "爬山"
}

这里就和上面有些不一样了, country添加的时候,是用的自己的id去路由的,rd_center添加的时候,指定了parent id,所以他也是用的country 的id去路由的, 但是employee在添加的时候如果也是仅仅指定一个parent,那就表示用的是rd_center的id去路由,这就可能导致,这三种数据不在一个shard上.

所以孙子辈儿的doc添加的时候除了指定parent还需要加一个routing,值是爷爷辈儿的数据的id

搜索案例

需求: 搜索有爬山爱好的员工所在的国家

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GET /company/country/_search
{
"query": {
"has_child": {
"type": "rd_center",
"query": {
"has_child": {
"type": "employee",
"query": {
"match": {
"hobby": "爬山"
}
}
}
}
}
}
}

返回值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"took": 24,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "company",
"_type": "country",
"_id": "1",
"_score": 1,
"_source": {
"name": "中国"
}
}
]
}
}

需要一级一级用has_child去找