elasticsearch的父子关系
2022-02-27 本文已影响0人
virtual灬zzZ
当文档索引性能远比查询性能重要的时候,父子关系是非常有用的,但是它也是有巨大代价的。其查询速度会比同等的嵌套查询慢5到10倍!
全局序号和延迟
父子关系使用了全局序数 来加速文档间的联合。不管父子关系映射是否使用了内存缓存或基于硬盘的 doc values,当索引变更时,全局序数要重建。
一个分片中父文档越多,那么全局序数的重建就需要更多的时间。父子关系更适合于父文档少、子文档多的情况。
多代使用和结语
多代文档的联合查询(查看 祖辈与孙辈关系)虽然看起来很吸引人,但必须考虑如下的代价:
- 联合越多,性能越差。
- 每一代的父文档都要将其字符串类型的
_id
字段存储在内存中,这会占用大量内存。
当你考虑父子关系是否适合你现有关系模型时,请考虑下面这些建议:
- 尽量少地使用父子关系,仅在子文档远多于父文档时使用。
- 避免在一个查询中使用多个父子联合语句。
- 在 has_child 查询中使用 filter 上下文,或者设置 score_mode 为 none 来避免计算文档得分。
- 保证父 IDs 尽量短,以便在 doc values 中更好地压缩,被临时载入时占用更少的内存。
最重要的是: 先考虑下我们之前讨论过的其他方式来达到父子关系的效果。

建模和模拟数据
PUT parent_and_child
{
"mappings": {
"properties": {
"company": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "text"
}
}
},
"employee": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "text"
},
"companyId": {
"type": "integer"
}
}
},
"relation": {
"type": "join",
"relations": {
"company": [
"employee"
]
}
}
}
}
}
GET /parent_and_child/_mapping
######父数据
POST parent_and_child/_doc/1
{
"company.id":1,
"relation":"company",
"company.name":"广东分公司"
}
POST parent_and_child/_doc/2
{
"company.id":2,
"relation":"company",
"company.name":"湖南分公司"
}
#####子数据
POST parent_and_child/_doc/101?routing=1
{
"employee.id":101,
"relation":{
"name":"employee",
"parent":"1"
},
"employee.name":"广东小强",
"employee.companyId":1
}
POST parent_and_child/_doc/102?routing=1
{
"employee.id":102,
"relation":{
"name":"employee",
"parent":1
},
"employee.name":"广东小明",
"employee.companyId":1
}
POST parent_and_child/_doc/103?routing=2
{
"employee.id":103,
"relation":{
"name":"employee",
"parent":"2"
},
"employee.name":"湖南小勇",
"employee.companyId":2
}
POST parent_and_child/_doc/104?routing=2
{
"employee.id":104,
"relation":{
"name":"employee",
"parent":2
},
"employee.name":"湖南小希",
"employee.companyId":2
}
POST parent_and_child/_doc/105?routing=2
{
"employee.id":105,
"relation":{
"name":"employee",
"parent":2
},
"employee.name":"湖南小若",
"employee.companyId":2
}
GET /parent_and_child/_doc/_search
以子查父
GET /parent_and_child/_doc/_search
{
"query":{
"has_child":{
"type":"employee",
"min_children":2,
"query":{
"terms":{
"employee.companyId": [1,2]
}
}
}
}
}
以子查父,查出父子级联信息
GET /parent_and_child/_doc/_search
{
"query":{
"has_child":{
"type":"employee",
"query":{
"terms":{
"employee.companyId": [1,2]
}
},
"inner_hits":{}
}
}
}
以父查子
GET /parent_and_child/_doc/_search
{
"query":{
"has_parent":{
"parent_type":"company",
"query":{
"match":{
"company.name":"广东"
}
}
}
}
}