I need to index 3 levels (or more) of child-parent. For example, the levels might be an author, a book, and characters from that book.
However, when indexing more than t
For the grandpa docs, you need to get the _id as the _routing. For the father docs, just use the _parent (grandpa._id) as the _routing. For the children docs, just use the grandpa._id as the _routing.
You are correct, parent/child relationship can only work when all children of a given parent resides in the same shard as the parent. Elasticsearch achieves this by using parent id as a routing value. It works great on one level. However, it breaks on the second and consecutive levels. When you have parent/child/grandchild relationship parents are routed based on their id, children are routed based on the parent ids (works), but then grandchildren are routed based on the children ids and they end up in wrong shards. To demonstrate it on an example, let's assume that we are indexing 3 documents:
curl -XPUT localhost:9200/test-idx/author/Douglas-Adams -d '{...}'
curl -XPUT localhost:9200/test-idx/book/Mostly-Harmless?parent=Douglas-Adams -d '{...}'
curl -XPUT localhost:9200/test-idx/character/Arthur-Dent?parent=Mostly-Harmless -d '{...}'
Elasticsearch uses value Douglas-Adams
to calculate routing for the document Douglas-Adams
- no surprise here. For the document Mostly-Harmless
, Elasticsearch sees that it has parent Douglas-Adams
, so it uses again Douglas-Adams
to calculate routing and everything is good - same routing value means same shard. But for the document Arthur-Dent
Elasticsearch sees that it has parent Mostly-Harmless
, so it uses value Mostly-Harmless
as a routing and as a result document Arthur-Dent
ends up in wrong shard.
The solution for this is to explicitly specify routing value for the grandchildren equal to the id of the grandparent:
curl -XPUT localhost:9200/test-idx/author/Douglas-Adams -d '{...}'
curl -XPUT localhost:9200/test-idx/book/Mostly-Harmless?parent=Douglas-Adams -d '{...}'
curl -XPUT localhost:9200/test-idx/character/Arthur-Dent?parent=Mostly-Harmless&routing=Douglas-Adams -d '{...}'