原文地址: https://www.elastic.co/guide/cn/elasticsearch/guide/current/indexing-parent-child.html, 版权归 www.elastic.co 所有
英文版地址: https://www.elastic.co/guide/en/elasticsearch/guide/current/indexing-parent-child.html
英文版地址: https://www.elastic.co/guide/en/elasticsearch/guide/current/indexing-parent-child.html
请注意:
本书基于 Elasticsearch 2.x 版本,有些内容可能已经过时。
本书基于 Elasticsearch 2.x 版本,有些内容可能已经过时。
构建父-子文档索引edit
为父文档创建索引与为普通文档创建索引没有区别。父文档并不需要知道它有哪些子文档。
POST /company/branch/_bulk { "index": { "_id": "london" }} { "name": "London Westminster", "city": "London", "country": "UK" } { "index": { "_id": "liverpool" }} { "name": "Liverpool Central", "city": "Liverpool", "country": "UK" } { "index": { "_id": "paris" }} { "name": "Champs Élysées", "city": "Paris", "country": "France" }
创建子文档时,用户必须要通过 parent
参数来指定该子文档的父文档 ID:
PUT /company/employee/1?parent=london { "name": "Alice Smith", "dob": "1970-10-24", "hobby": "hiking" }
父文档parent
的 ID 有两个作用:1). 创建父文档和子文档之间的关系,2). 保证父文档和子文档都在同一个分片上。
在 路由一个文档到一个分片 中,我们解释了 Elasticsearch 如何通过路由值来决定该文档属于哪一个分片,路由值默认为该文档的 _id
。分片路由的计算公式如下:
shard = hash(routing) % number_of_primary_shards
如果指定了parent
ID,那么就会使用父文档的 ID 进行路由,而不会使用当前文档_id
。也就是说,如果父文档和子文档都使用相同的值进行路由,那么父文档和子文档都会分布在同一个分片上。
在执行单文档的请求时需要指定parent
ID,单文档请求包括:通过 GET
请求获取一个子文档;创建、更新或删除一个子文档。
与转发到索引中的所有分片的搜索请求不同,这些单文档请求只转发到保存文档的分片 —— 如果没有指定parent
ID,请求可能会被转发到错误的分片。
parent
ID 应该在bulk
API中指定:
POST /company/employee/_bulk { "index": { "_id": 2, "parent": "london" }} { "name": "Mark Thomas", "dob": "1982-05-16", "hobby": "diving" } { "index": { "_id": 3, "parent": "liverpool" }} { "name": "Barry Smith", "dob": "1979-04-01", "hobby": "hiking" } { "index": { "_id": 4, "parent": "paris" }} { "name": "Adrien Grand", "dob": "1987-05-11", "hobby": "horses" }
如果你想要改变一个子文档的 parent
值,仅通过更新这个子文档是不够的,因为新的父文档有可能在另外一个分片上。因此,你必须要先把子文档删除,然后再重新索引这个子文档。