Parent/Child/GrandChild

HI,

I have a question about ES and Parent/Child :

is it possible to have nested has_child filter (or query) ? now, we are
trying to post a query with 2 levels of child (parent/child/grandchild).

example of mapping :
{
"settings":{
"analysis":{
"analyzer":{
"key_lowercase":{
"tokenizer":"keyword",
"filter":"lowercase"
}
}
},
"index":{
"number_of_shards":5,
"number_of_replicas":1
}
},
"mappings":{
"type0":{
"properties":{...}
},
"type1":{
"_parent":{
"type":"type0"
},
"properties":{...}
}
"type2":{
"_parent":{
"type":"type1"
},
"properties":{...}
}
}
}

*example of query :
*
{
"query" : {
"filtered" : {
"query" : {
"bool" : {
"must" : [{...}, {...}]
}
},
"filter" : {
"has_child" : {
"type" : "type1",
"query" : {
"filtered" : {
"query" : {
"bool" : {
"must" : [{...}]
}
},
"filter" : {
"has_child" : {
"type" : "type2",
"query" : {
"term" : {...}
}
}
}
}
}
}
}
}
}
}

Thanks.

Yes, its possible. One thing that you need to make sure is to have the routing value when indexing of the grandchild to be the id of the top most parent (so they end up in the same shard), on top of having its parent set to be the "father".

On Tuesday, February 7, 2012 at 3:52 PM, Ludovic wrote:

HI,

I have a question about ES and Parent/Child :

is it possible to have nested has_child filter (or query) ? now, we are trying to post a query with 2 levels of child (parent/child/grandchild).

example of mapping :
{
"settings":{
"analysis":{
"analyzer":{
"key_lowercase":{
"tokenizer":"keyword",
"filter":"lowercase"
}
}
},
"index":{
"number_of_shards":5,
"number_of_replicas":1
}
},
"mappings":{
"type0":{
"properties":{...}
},
"type1":{
"_parent":{
"type":"type0"
},
"properties":{...}
}
"type2":{
"_parent":{
"type":"type1"
},
"properties":{...}
}
}
}

example of query :

{
"query" : {
"filtered" : {
"query" : {
"bool" : {
"must" : [{...}, {...}]
}
},
"filter" : {
"has_child" : {
"type" : "type1",
"query" : {
"filtered" : {
"query" : {
"bool" : {
"must" : [{...}]
}
},
"filter" : {
"has_child" : {
"type" : "type2",
"query" : {
"term" : {...}
}
}
}
}
}
}
}
}
}
}

Thanks.

Thanks for your reply,
but it still does not work. We have changed the mapping with the "_routing"
field added to the grandchild and the child like this :
{
"settings":{
"analysis":{
"analyzer":{
"key_lowercase":{
"tokenizer":"keyword",
"filter":"lowercase"
}
}
},
"index":{
"number_of_shards":5,
"number_of_replicas":1
}
},
"mappings":{
"type0":{
"properties":{...}
},
"type1":{
"_parent":{
"type":"type0"
},
"_routing":{
"required":true,
"path":"idDoc" //where idDoc has the same value that the _id of my
type0 document.
},
"properties":{
"idDoc":{
"type":"string"
}
}
}
"type2":{
"_parent":{
"type":"type1"
},
"_routing":{
"required":true,
"path":"idDoc" //where idDoc has the same value that the _id of my
type0 document.
},
"properties":{
"idDoc":{
"type":"string"
}
}
}
}
}

with the same query (above), we have these failures :

[2012-02-17 15:22:33,224][DEBUG][action.search.type ] [Firebird]
[dau-pc-routing][1], node[x9dPP-onRzelU61efTc_Ow], [P], s[STARTED]: Failed
to execute [org.elasticsearch.action.search.SearchRequest@164b517]
org.elasticsearch.search.query.QueryPhaseExecutionException:
[dau-pc-routing][1]: query[filtered(filtered(+document.nbArticles:{0 TO *]
+document.dateEtablissementDeclaration:[1293840000000 TO
*])->child_filter[SA/SG](filtered(filtered(document.articles.masseNette:{0.0
TO
*])->child_filterSA_DOCUMENTS/SA)->FilterCacheFilterWrapper(_type:SA)))->FilterCacheFilterWrapper(org.elasticsearch.index.search.nested.NonNestedDocsFilter@a2a5984b)],from[0],size[10]:
Query Failed [Failed to execute child query
[filtered(filtered(document.articles.masseNette:{0.0 TO
*])->child_filterSA_DOCUMENTS/SA)->FilterCacheFilterWrapper(_type:SA)]]
at
org.elasticsearch.search.query.QueryPhase.execute(QueryPhase.java:164)
at
org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:238)
at
org.elasticsearch.search.action.SearchServiceTransportAction.sendExecuteQuery(SearchServiceTransportAction.java:134)
at
org.elasticsearch.action.search.type.TransportSearchQueryThenFetchAction$AsyncAction.sendExecuteFirstPhase(TransportSearchQueryThenFetchAction.java:80)
at
org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction.performFirstPhase(TransportSearchTypeAction.java:205)
at
org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction.performFirstPhase(TransportSearchTypeAction.java:192)
at
org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction$2.run(TransportSearchTypeAction.java:178)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown
Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at
org.elasticsearch.index.search.child.HasChildFilter.getDocIdSet(HasChildFilter.java:85)
at
org.apache.lucene.search.FilteredQuery.getFilteredScorer(FilteredQuery.java:136)
at
org.apache.lucene.search.FilteredQuery$1.scorer(FilteredQuery.java:117)
at
org.apache.lucene.search.FilteredQuery.getFilteredScorer(FilteredQuery.java:149)
at
org.apache.lucene.search.FilteredQuery$1.scorer(FilteredQuery.java:117)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:577)
at
org.elasticsearch.search.internal.ContextIndexSearcher.search(ContextIndexSearcher.java:199)
at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:383)
at
org.elasticsearch.search.query.QueryPhase.execute(QueryPhase.java:157)
... 9 more

why ?