Elasticsearch 父子文档
介绍
在 Elasticsearch 中,父子文档(Parent-Child Documents)是一种用于建模一对多关系的机制。通过父子文档,您可以将一个文档(父文档)与多个其他文档(子文档)关联起来。这种关系特别适用于需要表示层次结构或复杂关系的场景,例如博客文章与评论、订单与订单项等。
与嵌套文档(Nested Documents)不同,父子文档允许子文档独立于父文档进行索引和查询。这种独立性使得父子文档在处理大规模数据时更加灵活和高效。
父子文档的基本概念
1. 父子关系的定义
在 Elasticsearch 中,父子关系是通过在映射(Mapping)中定义的。您需要为父文档和子文档分别创建索引,并在子文档的映射中指定父文档的类型。
例如,假设我们有一个博客系统,其中博客文章是父文档,评论是子文档。我们可以这样定义映射:
PUT /blog
{
"mappings": {
"properties": {
"post_id": { "type": "keyword" },
"content": { "type": "text" },
"comments": {
"type": "join",
"relations": {
"post": "comment"
}
}
}
}
}
在这个映射中,post
是父文档类型,comment
是子文档类型。
2. 索引父文档和子文档
父文档和子文档需要分别索引。父文档的索引方式与普通文档相同,而子文档在索引时需要指定其父文档的 ID。
例如,索引一篇博客文章(父文档):
PUT /blog/_doc/1
{
"post_id": "1",
"content": "This is a blog post about Elasticsearch.",
"comments": {
"name": "post"
}
}
然后,索引一条评论(子文档):
PUT /blog/_doc/2?routing=1
{
"comment_id": "2",
"content": "Great post!",
"comments": {
"name": "comment",
"parent": "1"
}
}
注意,子文档在索引时需要指定 routing
参数,以确保它与父 文档存储在同一个分片中。
3. 查询父子文档
Elasticsearch 提供了多种查询方式来检索父子文档。例如,您可以使用 has_child
查询来查找包含特定子文档的父文档,或者使用 has_parent
查询来查找属于特定父文档的子文档。
例如,查找所有包含评论的博客文章:
GET /blog/_search
{
"query": {
"has_child": {
"type": "comment",
"query": {
"match_all": {}
}
}
}
}
或者,查找属于特定博客文章的所有评论:
GET /blog/_search
{
"query": {
"has_parent": {
"parent_type": "post",
"query": {
"match": {
"post_id": "1"
}
}
}
}
}