# Querying a multiple level nested object

**URL:** https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889
**Category:** Elasticsearch
**Created:** [August 1, 2016, 12:18pm UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889 "2016-08-01T12:18:01Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![gigouni](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/gigouni/32/9920_2.png) [@gigouni](https://discuss.elastic.co/u/gigouni)
#### Post date: [August 1, 2016, 12:18pm UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889/1 "2016-08-01T12:18:01Z")

</div>

Hello everyone,

I would like to precise that I've searched before annoy you with my question but I didn't found the answer on Google or even through this forum (but maybe that it has already been asked somewhere with some other keywords).

Here is the concerned mapping :

```
body: {
	categories: {
		type: "nested",
		properties: {
			name: { type: "string" },
			list: {
				type: "nested",
				properties: {
					url_site: { type: "string" },
					persons: {
						total_customers: { type: "integer" },
						total_subscribers: { type: "integer" },
						details: {
							type: "nested",
							properties: {
								person_id: { type: "string" },
								person_date_registration: { type: "date" },
								person_date_subscription: { type: "date" }
							}
						}
					}
				}
			}
		}
	}
}

```

Yeah, I know, complex mapping. But my question is kind of tricky. I'm trying to do a research through the javascript API like this :

```
elasticClient.search({
	index: indexName,
	type: typeName,
	q: customer_id
}).then(function (body) {
	return body.hits.hits[0];
}, function (err) {
	console.trace("\nTRACE : " + err.message);
});

```

Do you know how I could pass a correct q parameter to search all the persons with the person\_id equals to my customer\_id ?

I tried the following using SENSE but failed (hard customer ID given):

```
POST /indexName/typeName/_search
{
   "query": {
      "bool": {
         "must": {
            "match": {
               "categories.list.persons.details.person_id": "50"
            }
         }
      }
   }
}

```

and even

```
POST /indexName/typeName/_search
{
   "query": {
      "nested": {
         "path": "categories[0].list[0].persons",
         "query": {
            "bool": {
               "must": [
                  {
                     "match": {
                        "categories[0].list[0].persons.id": 50
                     }
                  }
               ]
            }
         }
      }
   }
}

```

You guys already help me a lot with ElasticSearch and I know that here is the best place to ask this question.

Have a good day.

A lost intern.

---

<div class="post-metadata">

### Author: ![gigouni](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/gigouni/32/9920_2.png) [@gigouni](https://discuss.elastic.co/u/gigouni)
#### Post date: [August 3, 2016, 12:16pm UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889/2 "2016-08-03T12:16:43Z")

</div>

Still working on this problem, I think that it's almost done. Thanks to the help of Github and its issues part, I've done this for the moment :

```
 POST index/type/_search
{
   "_source": false,
   "query": {
      "nested": {
         "path": "categories",
         "query": {
            "nested": {
               "path": "categories.list",
               "query": {
                  "nested": {
                     "path": "categories.list.persons",
                     "query": {
                        "nested": {
                           "path": "categories.list.persons.details",
                           "query": {
                              "match": {
                                 "categories.list.persons.details.person_id": "50"
                              }
                           }
                        }
                     }
                  }
               }
            }
         },
         "inner_hits": {}
      }
   }
}

```

It's not perfect and returns an error about nested item but I continue to work on it. This answer aims to help people who could be in the same case than me, with multiple level of nested objects.

I've followed the instructions of this issue : [https://github.com/elastic/elasticsearch/issues/11830](https://github.com/elastic/elasticsearch/issues/11830)

If you have the solution, here the error returned :

```
{
   "error": {
      "root_cause": [
         {
            "type": "query_parsing_exception",
            "reason": "[nested] nested object under path [categories.list.persons] is not of nested type",
            "index": "index",
            "line": 11,
            "col": 22
         }
      ],
      "type": "search_phase_execution_exception",
      "reason": "all shards failed",
      "phase": "query",
      "grouped": true,
      "failed_shards": [
         {
            "shard": 0,
            "index": "index",
            "node": "nodeID",
            "reason": {
               "type": "query_parsing_exception",
               "reason": "[nested] nested object under path [categories.list.persons] is not of nested type",
               "index": "index",
               "line": 11,
               "col": 22
            }
         }
      ]
   },
   "status": 400
}

```

Have a nice day

---

<div class="post-metadata">

### Author: ![cbuescher](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/cbuescher/32/60402_2.png) [@cbuescher](https://discuss.elastic.co/u/cbuescher)
#### Post date: [August 3, 2016, 2:17pm UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889/3 "2016-08-03T14:17:31Z")

</div>

> [@gigouni](#):
>
> "reason": "[nested] nested object under path [categories.list.persons] is not of nested type"

This error message suggests you haven't defined a type for the `persons` field. At least I can't see one in your initial posting. I'm still wondering if you really need that deep level of nested objects or if you could flatten the structure. This depends on what you do with this kind of documents though.

---

<div class="post-metadata">

### Author: ![gigouni](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/gigouni/32/9920_2.png) [@gigouni](https://discuss.elastic.co/u/gigouni)
#### Post date: [August 3, 2016, 2:33pm UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889/4 "2016-08-03T14:33:56Z")

</div>

Hello @cbuescher

Nice memory of the project. I have to admit that this architecture might not be the best one but it has been "validated" by my bosses and it was my really first experience with NoSQL. Nobody know ElasticSearch in my company so I have to handle it alone. I've tried to have the best model but I failed on some points. If I had enough time to think about it and reset the mapping from scratch, I would (but my internship is almost done and I really have to succeed with this request).

Concerning the request, I'm still unable to find the correct structure. It seems to be good until the "persons" object. I don't know how to pass it to go the next nested level. I'm blocked with this request which currently return all the data in my index/type :

```
POST sa_bigbrother/sites/_search
{
   "query": {
      "nested": {
         "path": "categories",
         "query": {
            "nested": {
               "path": "categories.list",
               "query": {
                  "nested": {
                     "path": "categories.list.persons.details",
                     "query": {
                        "bool": {
                           "must": {
                              "match": {
                                 "categories.list.persons.details.person_id": "50"
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   },
   "inner_hits": {}
}

```

Do you know how I should process?

---

<div class="post-metadata">

### Author: ![cbuescher](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/cbuescher/32/60402_2.png) [@cbuescher](https://discuss.elastic.co/u/cbuescher)
#### Post date: [August 3, 2016, 2:55pm UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889/5 "2016-08-03T14:55:54Z")

</div>

Hi,  
I tried to recreate your mapping (not 100% exactly probably, but more or less) and your query worked for me, just returning one user with that id. Here's what I did, you can compare that to your own mapping to spot possible differences:

```auto
PUT /nested_test
{
  "mappings": {
    "t": {
      "properties": {
        "categories": {
          "type": "nested",
          "properties": {
            "name": {
              "type": "string"
            },
            "list": {
              "type": "nested",
              "properties": {
                "url_site": {
                  "type": "string"
                },
                "persons": {
                  "type": "nested",
                  "properties": {
                    "total_customers": {
                      "type": "integer"
                    },
                    "total_subscribers": {
                      "type": "integer"
                    },
                    "details": {
                      "type": "nested",
                      "properties": {
                        "person_id": {
                          "type": "string"
                        },
                        "person_date_registration": {
                          "type": "date"
                        },
                        "person_date_subscription": {
                          "type": "date"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

PUT /nested_test/t/1
{
  "categories" : {
    "name" : "cat1",
    "list" : {
      "url_site" : "www.bla.org",
      "persons" : {
        "total_customers" : 10,
        "total_subscribers" : 10,
        "details" : {
          "person_id" : 1
        }
      }
    }
  }
}

PUT /nested_test/t/2
{
  "categories" : {
    "name" : "cat2",
    "list" : {
      "url_site" : "www.bleep.org",
      "persons" : {
        "total_customers" : 10,
        "total_subscribers" : 10,
        "details" : {
          "person_id" : 2
        }
      }
    }
  }
}

PUT /nested_test/t/3
{
  "categories" : {
    "name" : "cat3",
    "list" : {
      "url_site" : "www.blubb.org",
      "persons" : {
        "total_customers" : 10,
        "total_subscribers" : 10,
        "details" : {
          "person_id" : 3
        }
      }
    }
  }
}

POST /nested_test/t/_search
{
  "query": {
    "nested": {
      "path": "categories",
      "query": {
        "nested": {
          "path": "categories.list",
          "query": {
            "nested": {
              "path": "categories.list.persons.details",
              "query": {
                "bool": {
                  "must": {
                    "match": {
                      "categories.list.persons.details.person_id": 1
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

returns ==>

"hits": {
    "total": 1,
    "max_score": 1.9162908,
    "hits": [
      {
        "_index": "nested_test",
        "_type": "t",
        "_id": "1",
        "_score": 1.9162908,
        "_source": {
          "categories": {
            "name": "cat1",
            "list": {
              "url_site": "www.bla.org",
              "persons": {
                "total_customers": 10,
                "total_subscribers": 10,
                "details": {
                  "person_id": 1
                }
              }
            }
          }
        }
      }
    ]
  }

```

btw. if you are just interested in the document without scoring, you can use the `filter` section in the `match`query instead of `must`.

---

<div class="post-metadata">

### Author: ![gigouni](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/gigouni/32/9920_2.png) [@gigouni](https://discuss.elastic.co/u/gigouni)
#### Post date: [August 3, 2016, 3:24pm UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889/6 "2016-08-03T15:24:02Z")

</div>

God bless you for trying to help a desperate intern.

I've tried your example and when I add another person in "cat1" and retry your request, it returns me the other person too. If I have to get the parent data, it's still cool but I cannot get all the data for this request, only the customer which answer to the filter or I will burst the stack overflow.

To not say silly stuff, I tried to use the filter like you said but unfortunately It returns the same result.

---

<div class="post-metadata">

### Author: ![cbuescher](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/cbuescher/32/60402_2.png) [@cbuescher](https://discuss.elastic.co/u/cbuescher)
#### Post date: [August 3, 2016, 3:28pm UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889/7 "2016-08-03T15:28:07Z")

</div>

Sorry, I've re-run my example from above with all docs in "cat1" and I can filter for one person\_id only sucessfully with the given query. So this works for me. Make sure to closely look at the differences between that example and your real setup, hope you find those differences and get your own query working.

---

<div class="post-metadata">

### Author: ![gigouni](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/gigouni/32/9920_2.png) [@gigouni](https://discuss.elastic.co/u/gigouni)
#### Post date: [August 3, 2016, 3:36pm UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889/8 "2016-08-03T15:36:01Z")

</div>

Sorry, tiredness might be playing tricks on me. I'll double-check now!

---

<div class="post-metadata">

### Author: ![gigouni](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/gigouni/32/9920_2.png) [@gigouni](https://discuss.elastic.co/u/gigouni)
#### Post date: [August 3, 2016, 3:52pm UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889/9 "2016-08-03T15:52:33Z")

</div>

I've found a difference. It's about the "persons" object that **you set the type from "object" to "nested"**. 🙂

"persons" shouldn't be nested following what have been done. Is it a problem to set it as an object ? Or do I have to set it as a nested to navigate inside ?

If I set it as a nested object, it could be done by the fact that I won't push another "persons" object in this "site" object.

---

<div class="post-metadata">

### Author: ![cbuescher](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/cbuescher/32/60402_2.png) [@cbuescher](https://discuss.elastic.co/u/cbuescher)
#### Post date: [August 3, 2016, 4:00pm UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889/10 "2016-08-03T16:00:03Z")

</div>

> [@gigouni](#):
>
> Is it a problem to set it as an object

There's a good blog post about comparing object to nested here: [Managing Relations Inside Elasticsearch | Elastic Blog](https://www.elastic.co/blog/managing-relations-inside-elasticsearch)  
I think I can't give you a better explanation right now.

---

<div class="post-metadata">

### Author: ![Etibar\_HASANOV](https://avatars.discourse-cdn.com/v4/letter/e/7ab992/32.png) [@Etibar\_HASANOV](https://discuss.elastic.co/u/Etibar_HASANOV)
#### Post date: [May 2, 2017, 11:50am UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889/11 "2017-05-02T11:50:26Z")

</div>

Hello I have gone the same problem as you did. Had exactly the same problem you did, instead of match I used match\_phrase and it worked as a charm.

---

<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 5, 2017, 10:00pm UTC](https://discuss.elastic.co/t/querying-a-multiple-level-nested-object/56889/12 "2017-07-05T22:00:44Z")

</div>


