join数据类型允许在一个索引中的文档创建父子关系,通过维护父子文档的关系独立出来两个对象。父文档和自文档是相互独立的,通过类似引用的关系进行绑定,所以当父文档更新时,不需要更新自文档,而自文档可以被任意的添加、修改、删除而不会影响到父文档和其他自文档
需要注意的是,为了维护父子文档的关系需要占用额外的内存资源,并且读取性能相对较差。但是由于父子文档是互相独立的,所以适合自文档更新频率高的场景
在Mapping中定义join数据类型
PUT join_books_index
{
"mappings": {
"properties": {
"book_id": { "type": "keyword" },
"name": { "type": "text" },
"book_comments_relation": { # 定义字段名字
"type": "join", # 此字段为 join 类型
"relations": { # 声明 Parent / Child 的关系
"book": "comment" # book 是 Parent 的名称,comment 是 Child 的名称
}
}
}
},
"settings": {
"number_of_shards": 3, # 定义 3 个主分片
"number_of_replicas": 1
}
}
如上示例,book_comments_relation是字段的名字,使用join关键字定义此字段的类型为join类型,relations处声明了Parent/Child的关系,其中book是Parent的名称, comment是Child的名称
索引父文档(创建)
在定义了Mapping之后,我们写入父文档的数据
索引子文档(创建)
如上所示,book_comments_relation中声明了文档的类型为comment(即mapping中的自文档),并且使用parent字段指向父文档的id
为了确保查询时候的性能,父文档和子文档必须在同一个分片,所以需要强制使用routing参数,并且其值为父文档的Id(如果写入父文档的时候也用routing参数,那么需要保证他们的值是一样的)
数据检索
返回结果:
如图所示,我们在获取父文档的数据时候是不返回子文档的信息的,因为父子文档是相互独立的
获取子文档:
如上图所示,在获取子文档时,如果不加routing参数时,是无法找到对应的子文档的。routing参数的值为父文档的Id
parent id查询
如上所示,parent_id字段里面,我们查询了父文档Id为11并且comment类型的文档
返回结果:
has child查询
如果我们想查询用户“fork”评论了那些书本,可以使用 Has Child 查询。Has Child 查询将在子文档中进行条件匹配,然后返回匹配文档对应的父文档的信息
返回结果:
has parent查询
那如果我们想查询java相关书籍的评论时,可以使用Has Parent 查询。 Has Parent 查询会在父文档中进行匹配,然后返回匹配文档对应的子文档的信息。
返回结果: