# Nested has\_child query

**URL:** https://discuss.elastic.co/t/nested-has-child-query/10228
**Category:** Elasticsearch
**Created:** [January 4, 2013, 12:36pm UTC](https://discuss.elastic.co/t/nested-has-child-query/10228 "2013-01-04T12:36:10Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Przemek](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/przemek/32/2515_2.png) [@Przemek](https://discuss.elastic.co/u/Przemek)
#### Post date: [January 4, 2013, 12:36pm UTC](https://discuss.elastic.co/t/nested-has-child-query/10228/1 "2013-01-04T12:36:10Z")

</div>

Hello,  
I have an index, in which there are 3 types of document, call them parent  
-\> child -\> grandchild. So every grandchild's \_parent is some child, and  
every child's \_parent is some parent.

Performing these two queries yields correct results

curl -XPOST [http://localhost:9200/my\_index/parent/\_search](http://localhost:9200/my_index/parent/_search) -d '{  
"filter": {  
"has\_child": {  
"query": {  
"match\_all": {}  
},  
"type": "child"  
}  
},  
"from": 0,  
"query": {  
"match\_all": {}  
},  
"size": 10  
}'

curl -XPOST [http://localhost:9200/my\_index/child/\_search](http://localhost:9200/my_index/child/_search) -d '{  
"filter": {  
"has\_parent": {  
"parent\_type": "parent",  
"query": {  
"match\_all": {}  
}  
}  
},  
"from": 0,  
"query": {  
"match\_all": {}  
},  
"size": 10  
}'

But when doing a deeper query I get an empty list, even though there are  
correct values in ES:

curl -XPOST [http://localhost:9200/my\_index/child/\_search](http://localhost:9200/my_index/child/_search) -d '{  
"filter": {  
"has\_child": {  
"query": {  
"match\_all": {}  
},  
"type": "grandchild"  
}  
},  
"from": 0,  
"query": {  
"match\_all": {}  
},  
"size": 10  
}'

Also, the same seems to hold (i.e. empty list is returned) when trying to  
search for a parent that has children that have grandchildren:

curl -XPOST [http://localhost:9200/my\_index/parent/\_search/](http://localhost:9200/my_index/parent/_search/) -d '{  
"query": {  
"has\_child": {  
"type": "child",  
"query": {  
"has\_child": {  
"type": "grandchild",  
"query": {  
"match\_all": {}  
}  
}  
}  
}  
}  
}'

I'm using the most recent ElasticSearch server, i.e. 0.20.2

Could someone tell me what is the problem?

Cheers,  
Przemek

--

---

<div class="post-metadata">

### Author: ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)
#### Post date: [January 4, 2013, 1:52pm UTC](https://discuss.elastic.co/t/nested-has-child-query/10228/2 "2013-01-04T13:52:58Z")

</div>

When you indexed grandchildren, did you specify the routing of the top  
parent? In other words did you index grandchildren like this:

curl -XPUT  
"[http://localhost:9200/my\_index/grandchild/grandchild\_id?parent=child\_id&routing=parent\_id](http://localhost:9200/my_index/grandchild/grandchild_id?parent=child_id&routing=parent_id)"  
-d '{.....}'

or just

curl -XPUT  
"[http://localhost:9200/my\_index/grandchild/grandchild\_id?parent=child\_id](http://localhost:9200/my_index/grandchild/grandchild_id?parent=child_id)" -d  
'{.....}'

On Friday, January 4, 2013 7:36:10 AM UTC-5, Przemek wrote:

> Hello,  
> I have an index, in which there are 3 types of document, call them parent  
> -\> child -\> grandchild. So every grandchild's \_parent is some child, and  
> every child's \_parent is some parent.
> 
> Performing these two queries yields correct results
> 
> curl -XPOST [http://localhost:9200/my\_index/parent/\_search](http://localhost:9200/my_index/parent/_search) -d '{  
> "filter": {  
> "has\_child": {  
> "query": {  
> "match\_all": {}  
> },  
> "type": "child"  
> }  
> },  
> "from": 0,  
> "query": {  
> "match\_all": {}  
> },  
> "size": 10  
> }'
> 
> curl -XPOST [http://localhost:9200/my\_index/child/\_search](http://localhost:9200/my_index/child/_search) -d '{  
> "filter": {  
> "has\_parent": {  
> "parent\_type": "parent",  
> "query": {  
> "match\_all": {}  
> }  
> }  
> },  
> "from": 0,  
> "query": {  
> "match\_all": {}  
> },  
> "size": 10  
> }'
> 
> But when doing a deeper query I get an empty list, even though there are  
> correct values in ES:
> 
> curl -XPOST [http://localhost:9200/my\_index/child/\_search](http://localhost:9200/my_index/child/_search) -d '{  
> "filter": {  
> "has\_child": {  
> "query": {  
> "match\_all": {}  
> },  
> "type": "grandchild"  
> }  
> },  
> "from": 0,  
> "query": {  
> "match\_all": {}  
> },  
> "size": 10  
> }'
> 
> Also, the same seems to hold (i.e. empty list is returned) when trying to  
> search for a parent that has children that have grandchildren:
> 
> curl -XPOST [http://localhost:9200/my\_index/parent/\_search/](http://localhost:9200/my_index/parent/_search/) -d '{  
> "query": {  
> "has\_child": {  
> "type": "child",  
> "query": {  
> "has\_child": {  
> "type": "grandchild",  
> "query": {  
> "match\_all": {}  
> }  
> }  
> }  
> }  
> }  
> }'
> 
> I'm using the most recent Elasticsearch server, i.e. 0.20.2
> 
> Could someone tell me what is the problem?
> 
> Cheers,  
> Przemek

--

---

<div class="post-metadata">

### Author: ![Przemek](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/przemek/32/2515_2.png) [@Przemek](https://discuss.elastic.co/u/Przemek)
#### Post date: [January 4, 2013, 2:24pm UTC](https://discuss.elastic.co/t/nested-has-child-query/10228/3 "2013-01-04T14:24:22Z")

</div>

Yaaay! Works! Thank you, didn't have a clue that it has to be indexed this  
way. 🙂

Cheers,  
Przemek

On Friday, January 4, 2013 2:52:58 PM UTC+1, Igor Motov wrote:

> When you indexed grandchildren, did you specify the routing of the top  
> parent? In other words did you index grandchildren like this:
> 
> curl -XPUT "  
> [http://localhost:9200/my\_index/grandchild/grandchild\_id?parent=child\_id&routing=parent\_id](http://localhost:9200/my_index/grandchild/grandchild_id?parent=child_id&routing=parent_id)"  
> -d '{.....}'
> 
> or just
> 
> curl -XPUT "  
> [http://localhost:9200/my\_index/grandchild/grandchild\_id?parent=child\_id](http://localhost:9200/my_index/grandchild/grandchild_id?parent=child_id)" -d  
> '{.....}'
> 
> On Friday, January 4, 2013 7:36:10 AM UTC-5, Przemek wrote:
> 
> > Hello,  
> > I have an index, in which there are 3 types of document, call them parent  
> > -\> child -\> grandchild. So every grandchild's \_parent is some child, and  
> > every child's \_parent is some parent.
> > 
> > Performing these two queries yields correct results
> > 
> > curl -XPOST [http://localhost:9200/my\_index/parent/\_search](http://localhost:9200/my_index/parent/_search) -d '{  
> > "filter": {  
> > "has\_child": {  
> > "query": {  
> > "match\_all": {}  
> > },  
> > "type": "child"  
> > }  
> > },  
> > "from": 0,  
> > "query": {  
> > "match\_all": {}  
> > },  
> > "size": 10  
> > }'
> > 
> > curl -XPOST [http://localhost:9200/my\_index/child/\_search](http://localhost:9200/my_index/child/_search) -d '{  
> > "filter": {  
> > "has\_parent": {  
> > "parent\_type": "parent",  
> > "query": {  
> > "match\_all": {}  
> > }  
> > }  
> > },  
> > "from": 0,  
> > "query": {  
> > "match\_all": {}  
> > },  
> > "size": 10  
> > }'
> > 
> > But when doing a deeper query I get an empty list, even though there are  
> > correct values in ES:
> > 
> > curl -XPOST [http://localhost:9200/my\_index/child/\_search](http://localhost:9200/my_index/child/_search) -d '{  
> > "filter": {  
> > "has\_child": {  
> > "query": {  
> > "match\_all": {}  
> > },  
> > "type": "grandchild"  
> > }  
> > },  
> > "from": 0,  
> > "query": {  
> > "match\_all": {}  
> > },  
> > "size": 10  
> > }'
> > 
> > Also, the same seems to hold (i.e. empty list is returned) when trying to  
> > search for a parent that has children that have grandchildren:
> > 
> > curl -XPOST [http://localhost:9200/my\_index/parent/\_search/](http://localhost:9200/my_index/parent/_search/) -d '{  
> > "query": {  
> > "has\_child": {  
> > "type": "child",  
> > "query": {  
> > "has\_child": {  
> > "type": "grandchild",  
> > "query": {  
> > "match\_all": {}  
> > }  
> > }  
> > }  
> > }  
> > }  
> > }'
> > 
> > I'm using the most recent Elasticsearch server, i.e. 0.20.2
> > 
> > Could someone tell me what is the problem?
> > 
> > Cheers,  
> > Przemek

--

---

<div class="post-metadata">

### Author: ![Przemek](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/przemek/32/2515_2.png) [@Przemek](https://discuss.elastic.co/u/Przemek)
#### Post date: [January 4, 2013, 2:58pm UTC](https://discuss.elastic.co/t/nested-has-child-query/10228/4 "2013-01-04T14:58:15Z")

</div>

Out of curiosity: if I added one more level, i.e. grandgrandchild, how  
should I index it with

curl -XPUT  
'[http://localhost:9200/my\_index/grandgrandchild/grandgrandchild\_id?parent=grandchild\_id&routing=child\_id&routing=parent\_id](http://localhost:9200/my_index/grandgrandchild/grandgrandchild_id?parent=grandchild_id&routing=child_id&routing=parent_id)"  
-d '{...}'

or in some other manner?

Przemek

--

---

<div class="post-metadata">

### Author: ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)
#### Post date: [January 4, 2013, 3:42pm UTC](https://discuss.elastic.co/t/nested-has-child-query/10228/5 "2013-01-04T15:42:20Z")

</div>

The has\_child query can only work if both parent and child reside in the  
same shard. With one level, it's done automatically: parents are routed  
based on their ids (parent\_id) and when you index children you specify  
parent=parent\_id on URI, and elasticsearch is using parent\_id for routing  
instead of child\_id. When you index grandchildren, it's getting tricky,  
because they should be indexed into the same shard as their ancestors, but  
both parent=... value and their own ids might contain wrong routing value.  
That's way you have to specify correct routing value (id of the top parent)  
in the routing parameter. Similarly, when you are  
indexing grate-grandchild, you still need to specify the id of the top  
parent as a routing value to make sure that it will land in the same shards  
as all ancestors:

curl -XPUT '  
[http://localhost:9200/my\_index/grandgrandchild/grandgrandchild\_id?parent=grandchild\_id&routing=parent\_id](http://localhost:9200/my_index/grandgrandchild/grandgrandchild_id?parent=grandchild_id&routing=parent_id)[http://localhost:9200/my\_index/grandgrandchild/grandgrandchild\_id?parent=grandchild\_id&routing=child\_id&routing=parent\_id](http://localhost:9200/my_index/grandgrandchild/grandgrandchild_id?parent=grandchild_id&routing=child_id&routing=parent_id)"  
-d '{...}'

On Friday, January 4, 2013 9:58:15 AM UTC-5, Przemek wrote:

> Out of curiosity: if I added one more level, i.e. grandgrandchild, how  
> should I index it with
> 
> curl -XPUT '  
> [http://localhost:9200/my\_index/grandgrandchild/grandgrandchild\_id?parent=grandchild\_id&routing=child\_id&routing=parent\_id](http://localhost:9200/my_index/grandgrandchild/grandgrandchild_id?parent=grandchild_id&routing=child_id&routing=parent_id)"  
> -d '{...}'
> 
> or in some other manner?
> 
> Przemek

--

---

<div class="post-metadata">

### Author: ![Przemek](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/przemek/32/2515_2.png) [@Przemek](https://discuss.elastic.co/u/Przemek)
#### Post date: [January 5, 2013, 10:55am UTC](https://discuss.elastic.co/t/nested-has-child-query/10228/6 "2013-01-05T10:55:34Z")

</div>

OK, thank you for clarifying this.

Przemek

--

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)
#### Post date: [July 6, 2017, 2:57am UTC](https://discuss.elastic.co/t/nested-has-child-query/10228/7 "2017-07-06T02:57:49Z")

</div>


