原文链接 : 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 查询进行查询 :

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'