# _parent field

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

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

贡献者 : [朱彦安](/display/~zhuyanan)，[ApacheCN](/display/~apachecn)，[Apache中文网](/display/~apachechina)

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

```
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](https://www.elastic.co/guide/en/elasticsearch/reference/5.3/query-dsl-has-child-query.html)**  和 **[has_parent](https://www.elastic.co/guide/en/elasticsearch/reference/5.3/query-dsl-has-parent-query.html) **查询，**[children aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/5.3/search-aggregations-bucket-children-aggregation.html) **和 **[inner hits](https://www.elastic.co/guide/en/elasticsearch/reference/5.3/search-request-inner-hits.html#parent-child-inner-hits) **。

 该 **_parent** 字段的值可以在 **aggregations**（聚合）和 **scripts**（脚本）中访问，并且可以使用 **[parent_id](https://www.elastic.co/guide/en/elasticsearch/reference/5.3/query-dsl-parent-id-query.html) **查询进行查询 : 

```
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](https://www.elastic.co/guide/en/elasticsearch/reference/5.3/query-dsl-has-parent-query.html)** 查询和 [**has_child** ](https://www.elastic.co/guide/en/elasticsearch/reference/5.3/query-dsl-has-child-query.html)查询） |
| 2 | 在 **_parent** 字段上的聚合（参考 **[children aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/5.3/search-aggregations-bucket-children-aggregation.html)**） |
| 3 | 在脚本中访问 **_parent** 字段 |

### Parent-child restrictionsedit （父子限制）

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

### Global ordinals （全局序列）

父子使用 **[全局序列](https://www.elastic.co/guide/en/elasticsearch/reference/5.3/fielddata.html#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'
```