ElasticSearch 中的父子文档关系是一种用于表示层级或关联数据的设计模式。这种设计特别适用于需要对相关联的数据进行复杂查询和过滤的场景,例如分类商品、评论系统等。本文将详细介绍 ElasticSearch 父子文档关系的设计原理、使用方法以及实际应用场景。
在 ElasticSearch 中,父子文档关系通过 _parent
映射字段来实现。父文档和子文档必须存储在同一个索引中,并且它们之间的关系是单向的(即子文档知道它的父文档是谁,但父文档并不直接知道它有哪些子文档)。
_parent
字段关联到父文档,但父文档无法直接访问其子文档。在定义父子文档关系时,需要在索引映射中指定 _parent
字段。以下是一个简单的例子:
PUT /products
{
"mappings": {
"properties": {
"name": { "type": "text" },
"price": { "type": "float" }
}
}
}
PUT /categories
{
"mappings": {
"properties": {
"category_name": { "type": "text" }
}
}
}
PUT /items_with_parent
{
"mappings": {
"properties": {
"item_name": { "type": "text" },
"_parent": {
"type": "categories"
}
}
}
}
在上面的例子中,items_with_parent
是子文档索引,categories
是父文档索引。
插入父子文档时,需要指定 routing
和 parent
参数。以下是具体的步骤:
POST /categories/_doc/1
{
"category_name": "Electronics"
}
POST /items_with_parent/_doc/1?parent=1&routing=1
{
"item_name": "Laptop",
"price": 1000
}
parent=1
表示该子文档的父文档 ID 为 1
。routing=1
是为了确保父子文档被存储在相同的分片上。通过 has_parent
查询可以找到与特定父文档相关的子文档。例如:
GET /items_with_parent/_search
{
"query": {
"has_parent": {
"parent_type": "categories",
"query": {
"match": {
"category_name": "Electronics"
}
}
}
}
}
通过 has_child
查询可以找到与特定子文档相关的父文档。例如:
GET /categories/_search
{
"query": {
"has_child": {
"type": "items_with_parent",
"query": {
"range": {
"price": {
"gt": 500
}
}
}
}
}
}
routing
参数。假设我们有一个电商网站,商品需要按照分类进行展示。我们可以设计如下结构:
categories
)products
)当用户搜索某个分类下的商品时,可以使用 has_child
查询快速获取结果。
graph TD; A[开始] --> B{是否查询子文档}; B --是--> C[使用 has_parent 查询]; B --否--> D{是否查询父文档}; D --是--> E[使用 has_child 查询]; D --否--> F[结束];