elasticsearch 父子文档
官网:https://www.elastic.co/guide/en/elasticsearch/reference/7.13/parent-join.html
has parent query:https://www.elastic.co/guide/en/elasticsearch/reference/7.13/query-dsl-has-parent-query.html
has child query:https://www.elastic.co/guide/en/elasticsearch/reference/7.13/query-dsl-has-child-query.html
parent id query:https://www.elastic.co/guide/en/elasticsearch/reference/7.13/query-dsl-parent-id-query.html#parent-id-query-ex-request
children aggregation:https://www.elastic.co/guide/en/elasticsearch/reference/7.13/search-aggregations-bucket-children-aggregation.html
********************
join field type
join类型在同一个index内创建文档的父子关系
PUT my-index-000001
{
"mappings": {
"properties": {
"my_id": {
"type": "keyword"
},
"my_join_field": {
"type": "join", # my_join_field为join字段
"relations": {
"question": "answer" # question:父文档标识
} # answer:子文档标识
}
}
}
}
创建父文档
PUT my-index-000001/_doc/1?refresh
{
"my_id": "1",
"text": "This is a question",
"my_join_field": {
"name": "question"
}
}
# 简化写法
PUT my-index-000001/_doc/2?refresh
{
"my_id": "2",
"text": "This is another question",
"my_join_field": "question"
}
创建子文档
PUT my-index-000001/_doc/3?routing=1&refresh
{
"my_id": "3",
"text": "This is an answer",
"my_join_field": {
"name": "answer", # 子文档标识
"parent": "1" # 父文档id
}
}
说明:routing字段必须,父子文档必须在同一个分片(shard)上
性能说明
The join field shouldn’t be used like joins in a relation database.
In Elasticsearch the key to good performance is to de-normalize your
data into documents.
# join字段不应该该像关系型数据库那样使用,从性能方面考虑,可以进行反范式设计
Each join field, has_child or has_parent query adds a significant tax
to your query performance.
# join字段、has_child query、has_parent query都会影响查询性能
The only case where the join field makes sense is if your data contains
a one-to-many relationship where one entity significantly outnumbers
the other entity.
# join字段常用于一对多的关系
join 使用限制
Only one join field mapping is allowed per index.
# 同一个index最多只能使用一个join字段
Parent and child documents must be indexed on the same shard.
# 父子文档必须在同一个分片(shard)上
An element can have multiple children but only one parent.
# 一个文档可以有多个子文档,但最多只能有一个父文档
It is possible to add a new relation to an existing join field.
# 可以在join字段中添加新的关联关系(子文档可以成为其他文档的父文档)
It is also possible to add a child to an existing element but
only if the element is already a parent.
# 只能给父文档添加子文档
******************
多重父子关联(multiple levels of parent join)
PUT my-index-000001
{
"mappings": {
"properties": {
"my_join_field": {
"type": "join",
"relations": {
"question": ["answer", "comment"],
"answer": "vote"
}
}
}
}
}
说明:多重父子关联会影响查询性能,不推荐使用,
创建文档
# 文档 1
PUT my-index-000001/_doc/1?refresh
{
"my_id": "1",
"text": "This is a question",
"my_join_field": "question"
}
# 文档 2:文档 1的子文档
PUT my-index-000001/_doc/2?routing=1&refresh #routing的值为文档 1的路由id
{
"my_id": "3",
"text": "This is an answer",
"my_join_field": {
"name": "answer",
"parent": "1" # 父文档的id(文档 1