ES中通过join类型字段构建父子关联
一、功能描述:ES中支持非常丰富的关联查询实现方式,本节主要介绍如何通过join类型字段,实现同索引中的父子关联查询。二、Join field type1、介绍官网地址:Join field typejoin类型的字段主要用来在同一个索引中构建父子关联关系。通过relations定义一组父子关系,每个关系都包含一个父级关系名称和一个子级关系名称。例如:创建索引my_index,并在mappings
一、前言
ES中支持非常丰富的关联查询实现方式,本节主要介绍如何通过join类型字段,实现同索引中的父子关联查询。
二、Join field type
1、介绍
官网地址:Join field type
join类型的字段主要用来在同一个索引中构建父子关联关系。通过relations定义一组父子关系,每个关系都包含一个父级关系名称和一个子级关系名称。
示例:
创建索引my_index,并在mappings中指定关联字段my_join_field的type类型为join,
并通过relations属性指定关联关系,父级关系名称为question,子级关系名称为answer。
这里的父子级关系的名称可以自己定义,在向索引中添加数据时,需要根据定义的关系名称
指定my_join_field字段的值。
my_join_field关联字段的名称也可以自定义。
PUT my_index
{
"mappings": {
"properties": {
"text":{"type": "keyword"},
"my_join_field": {
"type": "join",
"relations": {
"question": "answer"
}
}
}
}
}
注意⚠️:
Join字段不能像关系型数据库中的join使用,在ES中为了保证良好的查询性能,最佳的实践是将数据模型设置为非规范化文档,也就是通过字段冗余构造宽表。
针对每一个join字段,has_child 或 has_parent 查询都会对您的查询性能造成重大影响。
补充说明:
_parent字段类型已经被移除,被join字段代替。
2、适用场景
数据中包含明显的一对多的关系,且其中一个实体的数量明显超过另一个实体。
比如:产品和产品报价信息。在报价明显超过产品数量的情况下,将产品建模为父文档并将报价建模为子文档是有意义的。
3、相关限制
1、一个索引中只能包含一个join字段
2、父子文档必须在同一个分片中
3、一个文档可以有多个子文档,但是只能有一个父文档。
4、可以给一个存在的join字段添加一个新的关联关系。
三、数据准备
1、添加父级数据
说明:
添加父级数据在关联字段my_join_field中,需要指定name名称为question,声明在join关联中是父级对象。
PUT my_index/_doc/1?refresh
{
"text": "我是第一个问题",
"my_join_field": {
"name": "question"
}
}
PUT my_index/_doc/2?refresh
{
"text": "我是第二个问题",
"my_join_field": {
"name": "question"
}
}
2、添加子级数据
说明:
添加子级数据时,在关联字段my_join_field中,需要指定name名称为answer,声明在join关联中是子级对象,同时在parent属性中指定父类id
并且在routing属性中指定父级数据的id,保证父子数据在索引的同一个分片中。
PUT my_index/_doc/3?routing=1&refresh
{
"text": "问题一的答案1",
"my_join_field": {
"name": "answer",
"parent": "1"
}
}
PUT my_index/_doc/4?routing=1&refresh
{
"text": "问题一的答案2",
"my_join_field": {
"name": "answer",
"parent": "1"
}
}
四、关联查询
1、根据parent_id查询
说明:
parent_id查询只能根据父id查询子数据。
GET my_index/_search
{
"query": {
"parent_id": {
"type": "answer",
"id": "1"
}
}
}
2、has_parent查询
说明:
has_parent用来查询满足条件的父类下的子数据
GET my_index/_search
{
"query": {
"has_parent": {
"parent_type": "question",
"query": {
"term": {
"text": {
"value": "我是第一个问题"
}
}
}
}
}
}
3、has_child查询
说明:
has_child用来根据子类条件查询满足条件的父类。
GET my_index/_search
{
"query": {
"has_child": {
"type": "answer",
"query": {
"term": {
"text": {
"value": "问题一的答案2"
}
}
}
}
}
}
五、多级关联
1、一父多子
PUT my-index-000001
{
"mappings": {
"properties": {
"my_join_field": {
"type": "join",
"relations": {
"question": ["answer", "comment"]
}
}
}
}
}
2、多层父子级
PUT my-index-000001
{
"mappings": {
"properties": {
"my_join_field": {
"type": "join",
"relations": {
"question": ["answer", "comment"],
"answer": "vote"
}
}
}
}
}
父子关系图:
注意⚠️:
实际使用中尽量避免使用多级关联。不但数据难于管理维护,查询性能也会非常地下。
总结:
本文主要介绍了在ES中如何通过join类型字段构建父子关联关系。
1、如何通过join字段在同一个索引中构建数据间的父子关联。
2、父子索引数据必须保证在同一分片中。
3、适用场景:数据中包含明显的一对多的关系。
4、父级可以有多个子级,但是一个子级只能对应一个父级。
5、has_child 或 has_parent 查询的使用
更多推荐
所有评论(0)