_parent field

原文链接 : https://www.elastic.co/guide/en/elasticsearch/reference/5.3/mapping-parent-field.html

译文链接 : http://www.apache.wiki/display/Elasticsearch/_parent+field

贡献者 : 朱彦安ApacheCNApache中文网

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

  1. curl -XPUT 'localhost:9200/my_index?pretty' -H 'Content-Type: application/json' -d'
  2. {
  3. "mappings": {
  4. "my_parent": {},
  5. "my_child": {
  6. "_parent": {
  7. "type": "my_parent" # 1
  8. }
  9. }
  10. }
  11. }
  12. '
  13. curl -XPUT 'localhost:9200/my_index/my_parent/1?pretty' -H 'Content-Type: application/json' -d' # 2
  14. {
  15. "text": "This is a parent document"
  16. }
  17. '
  18. curl -XPUT 'localhost:9200/my_index/my_child/2?parent=1&pretty' -H 'Content-Type: application/json' -d' # 2
  19. {
  20. "text": "This is a child document"
  21. }
  22. '
  23. curl -XPUT 'localhost:9200/my_index/my_child/3?parent=1&refresh=true&pretty' -H 'Content-Type: application/json' -d' # 4
  24. {
  25. "text": "This is another child document"
  26. }
  27. '
  28. curl -XGET 'localhost:9200/my_index/my_parent/_search?pretty' -H 'Content-Type: application/json' -d'
  29. {
  30. "query": {
  31. "has_child": { # 5
  32. "type": "my_child",
  33. "query": {
  34. "match": {
  35. "text": "child document"
  36. }
  37. }
  38. }
  39. }
  40. }
  41. '

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

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

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

  1. curl -XGET 'localhost:9200/my_index/_search?pretty' -H 'Content-Type: application/json' -d'
  2. {
  3. "query": {
  4. "parent_id": {
  5. "type": "my_child",
  6. "id": "1"
  7. }
  8. },
  9. "aggs": {
  10. "parents": {
  11. "terms": {
  12. "field": "_parent",
  13. "size": 10
  14. }
  15. }
  16. },
  17. "script_fields": {
  18. "parent": {
  19. "script": {
  20. "inline": "doc[\u0027_parent\u0027]"
  21. }
  22. }
  23. }
  24. }
  25. '

| 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 不频繁使用时,写入频繁发生,最好禁用预加载 :

  1. curl -XPUT 'localhost:9200/my_index?pretty' -H 'Content-Type: application/json' -d'
  2. {
  3. "mappings": {
  4. "my_parent": {},
  5. "my_child": {
  6. "_parent": {
  7. "type": "my_parent",
  8. "eager_global_ordinals": false
  9. }
  10. }
  11. }
  12. }
  13. '

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

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