Getting incorrect inner hits from parent child relationship when combined with boolean query

Hi Everyone

I am getting incorrect inner hits results when combining parent-child query with boolean query. To reproduce the issue, I create this Index


PUT /my-index-000001
{
  "mappings": {
    "_routing": {
      "required": true
    },
    "properties": {
      "parentProperty": {
        "type": "text"
      },
      "childProperty": {
        "type": "text"
      },
      "id": {
        "type": "integer"
      },
      "myJoinField": {
        "type": "join",
        "relations": {
          "parent": "mychild"
        }
      }
    }
  }
}

then I add these three documents (document with Id equals "1" is the parent of the other two documents)

POST /my-index-000001/_doc/1?routing=1
{
  "id": 1,
  "parentProperty": "a parent document",
  "myJoinField": "parent"
}

POST /my-index-000001/_doc/2?routing=1
{
  "id": 2,
  "childProperty": "queensland civil administration",
  "myJoinField": {
    "name":"mychild",
    "parent":"1"
  }
}

POST /my-index-000001/_doc/3?routing=1
{
  "id": 3,
  "childProperty": "beautiful weather",
  "myJoinField": {
    "name":"mychild",
    "parent":"1"
  }
}

now we set up our index with 3 documents. I am looking for all child documents that meet this boolean query: [childProperty contains either "queensland civil" or both "beautiful" and "nothing"].

I expect that elastic returns only the child document with Id "2" since the child document with Id "3" does not have the term "nothing" in it.

The translated version of this query is as follows:

GET /my-index-000001/_search
{
  "query": {
    "bool": {
      "minimum_should_match": 1, 
      "should": [
        {
          "has_child": {
            "inner_hits": {
              "name": "opr1"
            },
            "query": {
              "query_string": {
                "analyzer": "stop",
                "query": "childProperty:(\"queensland civil\")"
              }
            },
            "type": "mychild"
          }
        },
        {
          "bool": {
            "must": [
              {
                "has_child": {
                  "inner_hits": {
                    "name": "opr2"
                  },
                  "query": {
                    "query_string": {
                      "query": "childProperty:(beautiful)"
                    }
                  },
                  "type": "mychild"
                }
              },
              {
                "has_child": {
                  "inner_hits": {
                    "name": "opr3"
                  },
                  "query": {
                    "query_string": {
                      "query": "childProperty:(nothing)"
                    }
                  },
                  "type": "mychild"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

and the result that is returned from elasitc is as follows:

{
  "took" : 24,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my-index-000001",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_routing" : "1",
        "_source" : {
          "id" : 1,
          "parentProperty" : "a parent document",
          "myJoinField" : "parent"
        },
        "inner_hits" : {
          "opr1" : {
            "hits" : {
              "total" : {
                "value" : 1,
                "relation" : "eq"
              },
              "max_score" : 1.2814486,
              "hits" : [
                {
                  "_index" : "my-index-000001",
                  "_type" : "_doc",
                  "_id" : "2",
                  "_score" : 1.2814486,
                  "_routing" : "1",
                  "_source" : {
                    "id" : 2,
                    "childProperty" : "queensland civil administration",
                    "myJoinField" : {
                      "name" : "mychild",
                      "parent" : "1"
                    }
                  }
                }
              ]
            }
          },
          "opr2" : {
            "hits" : {
              "total" : {
                "value" : 1,
                "relation" : "eq"
              },
              "max_score" : 0.7549127,
              "hits" : [
                {
                  "_index" : "my-index-000001",
                  "_type" : "_doc",
                  "_id" : "3",
                  "_score" : 0.7549127,
                  "_routing" : "1",
                  "_source" : {
                    "id" : 3,
                    "childProperty" : "beautiful weather",
                    "myJoinField" : {
                      "name" : "mychild",
                      "parent" : "1"
                    }
                  }
                }
              ]
            }
          },
          "opr3" : {
            "hits" : {
              "total" : {
                "value" : 0,
                "relation" : "eq"
              },
              "max_score" : null,
              "hits" : [ ]
            }
          }
        }
      }
    ]
  }
}

as you can see in the result the elastic returns both child document which clearly is against what I have written in the "must" section of the query.

but if I rewrite the query as following then it will return the expected document:

GET /my-index-000001/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "has_child": {
            "inner_hits": {
              "name": "opr1"
            },
            "query": {
              "bool": {
                "minimum_should_match": 1, 
                "should": [
                  {
                    "query_string": {
                      "query": "childProperty:(\"queensland civil\")"
                    }
                  },
                  {
                    "bool": {
                      "must": [
                        {
                          "query_string": {
                            "query": "childProperty:(beautiful)"
                          }
                        },
                        {
                          "query_string": {
                            "query": "childProperty:(weather1)"
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            },
            "type": "mychild"
          }
        }
      ]
    }
  }
}

I appreciate it if someone tells me what I did wrong in the first query or if this is the default behavior in elasitc when it comes to parent/child relationship.

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