_parent field

通过使一个映射类型成为另一个映射类型的父类,可以在同一索引中的文档之间建立父子关系 : 

curl -XPUT 'localhost:9200/my_index?pretty' -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "my_parent": {},
    "my_child": {
      "_parent": {
        "type": "my_parent" # 1
      }
    }
  }
}
'
curl -XPUT 'localhost:9200/my_index/my_parent/1?pretty' -H 'Content-Type: application/json' -d' # 2
{
  "text": "This is a parent document"
}
'
curl -XPUT 'localhost:9200/my_index/my_child/2?parent=1&pretty' -H 'Content-Type: application/json' -d' # 2
{
  "text": "This is a child document"
}
'
curl -XPUT 'localhost:9200/my_index/my_child/3?parent=1&refresh=true&pretty' -H 'Content-Type: application/json' -d' # 4
{
  "text": "This is another child document"
}
'
curl -XGET 'localhost:9200/my_index/my_parent/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": {
    "has_child": { # 5
      "type": "my_child",
      "query": {
        "match": {
          "text": "child document"
        }
      }
    }
  }
}
'

| 1 | 该 my_parent 类型是 my_child 类型的 parent(父节)。 | | 2 | 索引 parent 文档。 | | 3 4 | 索引两个子文档,指定父文档的 ID。 | | 5 | 查找具有与查询匹配的子项的所有父文档。 |

有关更多信息,请参阅 has_child  和 has_parent 查询,children aggregation inner hits 

_parent 字段的值可以在 aggregations(聚合)和 scripts(脚本)中访问,并且可以使用 parent_id 查询进行查询 : 

curl -XGET 'localhost:9200/my_index/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": {
    "parent_id": { 
      "type": "my_child",
      "id": "1"
    }
  },
  "aggs": {
    "parents": {
      "terms": {
        "field": "_parent", 
        "size": 10
      }
    }
  },
  "script_fields": {
    "parent": {
      "script": {
         "inline": "doc[\u0027_parent\u0027]" 
      }
    }
  }
}
'

| 1 | 查询 _parent 字段的 id(参考 has_parent 查询和 has_child 查询) | | 2 | 在 _parent 字段上的聚合(参考 children aggregation) | | 3 | 在脚本中访问 _parent 字段 |

Parent-child restrictionsedit (父子限制)

  • 父类和子类型必须不同 - 不能在相同类型的文档之间建立父子关系。
  • _parent.type 设置只能指向不存在的类型。 这意味着类型在创建后不能成为父类型。
  • 父文档和子文档必须在相同的分片上索引。 父 ID 用作子节点的路由值,以确保子节点与父节点在同一分片上进行索引。 这意味着在获取,删除或更新子文档时需要提供相同的 parent 值。

Global ordinals (全局序列)

父子使用 全局序列 来加快连接。 在对分片进行任何更改之后,需要重建全局序列。 分片中存储的父 ID 值越多,重建 _parent 字段的全局序列所需的时间越长。

默认情况下,全局序列是高效的:如果索引已更改,则 _parent 字段的全局序列将作为刷新的一部分进行重新构建。 这会增加刷新时间。 然而,大多数时候,这是正确的选择,否则,当使用第一个 parent-child query(父子查询)或 aggregation(聚合)时,全局序列将被重建。 这可能会为您的用户带来较大的延迟,并且通常会更糟,因为在发生许多写入时,可能会在单个刷新间隔内重新创建 _parent 字段的多个全局序列。

当 parent/child 不频繁使用时,写入频繁发生,最好禁用预加载 : 

curl -XPUT 'localhost:9200/my_index?pretty' -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "my_parent": {},
    "my_child": {
      "_parent": {
        "type": "my_parent",
        "eager_global_ordinals": false
      }
    }
  }
}
'

可以检查全局序列使用的堆数量,如下所示 : 

# Per-index
curl -XGET 'localhost:9200/_stats/fielddata?human&fields=_parent&pretty'
# Per-node per-index
curl -XGET 'localhost:9200/_nodes/stats/indices/fielddata?human&fields=_parent&pretty'