Elasticsearch OR query with nested objects returns inner_hits not matching the criteria

Hi:

I'm getting weird results when querying nested objects. Imagine the following structure:

{ owner.name = "fred",
  ...,
  pets [
    { name = "daisy", ... },
    { name = "flopsy", ... }
  ]
}

If I only have the document shown above, and I search pets matching this criteria:

pets.name = "daisy" OR
(owner.name = "julie" and pet.name = "flopsy")

I would expect to only get one result ("daisy"), but I'm getting both pet names.

This is one way to reproduce this:

# Create nested mapping
PUT pet-owners
{
  "mappings": {
    "animals": {
      "properties": {
        "owner": {"type": "text"},
        "pets": {
          "type": "nested",
          "properties": {
            "name": {"type": "text", "fielddata": true}
            }
          }
        }
     }
    }
}
 
# Insert nested object
PUT pet-owners/animals/1?op_type=create
{
    "owner" : "fred",
    "pets"  : [
        { "name" : "daisy"},
        { "name" : "flopsy"}
  ]
}
 
# Query
GET pet-owners/_search
{ "from": 0, "size": 50,
  "query": {
    "constant_score": {
      "filter": { "bool": {"must": [
        {"bool": {"should": [
            {"nested": {"query":
              {"term": {"pets.name": "daisy"}},
              "path":"pets",
              "inner_hits": {
                "name": "pets_hits_1",
                "size": 99,
                "_source": false,
                "docvalue_fields": ["pets.name"]
              }
            }},
            {"bool": {"must": [
              {"term": {"owner": "julie"}},
              {"nested": {"query":
                {"term": {"pets.name": "flopsy"}},
                "path":"pets",
                "inner_hits": {
                  "name": "pets_hits_2",
                  "size": 99,
                  "_source": false,
                  "docvalue_fields": ["pets.name"]
                }
              }}
            ]}}
          ]}}
  ]}}}},
  "_source": false
}

The query returns both pets names (as opposed to the expected one).

Is this behavior normal? Am I doing something wrong, or my reasoning about the nested structure or the query behavior is flawed?

Any help or guidance will be much appreciated.

1 Like

Kind of unfortunate that no one has responded here. I understand that with nested docs, you are really querying that main index, and can't directly query the nested parts separately. But I'd really like to know how we can achieve what is being asked here.

Namely, I want the set of nested documents that match some criteria. But when that criteria includes an OR as in this example, you can see that things get muddled - you get all the inner_hits for the document that match.

When I've asked elsewhere some folks seem to think I should flatten and not use nested or use a separate index for the "children" and the "parent". But in my case, I can't flatten because the nested doc really has multiple fields and I want to query where some nested doc has multiple properties being true. And I also do want to join with the parent - so separate indexes make the join impossible.

I also did look at parent/child - but the advise here is always to avoid because of maintenance and performance concerns. Also with ES 6, it would seem that parent/child is advised against even more so - as we no longer have types (and my parent and child are certainly different types).

So is there a way to precisely get the set of nested docs that I'm looking for, even in the case of an OR condition as shown in the nice example by the original poster?

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.