Search code examples
elasticsearchnestednestelasticsearch-pluginelasticsearch-5

ElasticSearch Nested Query Does not work as expected


I need a quick help, i need to fetch the entire document only when my certain conditions are fulfilled in that same array.

Example

Conditions when in one array block all these three conditions fulfill. i.e.

  • "profile.bud.buddies.code": "1"
  • "profile.bud.buddies.moredata.key":"one"
  • "profile.bud.buddies.moredata.val": "0"

Unfortunately right now it is going through the entire document and trying to match the values in each of those arrays so it could be so that code=1 gets matched in one array, key=one in some other array and val=0 in the third array. What happens it in this case it returns me the entire document, whereas actually this was not fulfilled in one array alone so shouldn't have returned me the document.

I made the moredata as nested type but still cannot get through. Please help.

Query I am using

"query": {
    "bool": {
      "should": [
        {
          "match": {
            "profile.bud.buddies.code": "1"
          }
        }
      ]
    },
    "nested": {
    "path": "profile.bud.buddies.moredata",
    "query": {
      "bool": {
        "must": [
          {
            "match": {
              "profile.bud.buddies.moredata.key": "one"
            }
          },
          {
            "match": {
              "profile.bud.buddies.moredata.val": "0"
            }
          }
        ]
      }
    }
  }
}

Document Structure

"profile": {
  "x":{},
  "y":{},
  "a":{},
  "b":{},
  "bud":{
    "buddies": [
    {
        "code":"1",
        "moredata": [
            {
                "key": "one",
                "val": 0,
                "setup": "2323",
                "data": "myid"
            },
            {
                "key": "two",
                "val": 1,
                "setup": "23",
                "data": "id"
            }]
    },
    {
        "code":"2",
        "moredata": [
            {
                "key": "two",
                "val": 0,
                "setup": "2323",
                "data": "myid"
            },
            {
                "key": "three",
                "val": 1,
                "setup": "23",
                "data": "id"
            }]
    }]
}

This is how i have marked the mappings;

"profile": {
"bug": {
                                "properties": {
                                    "buddies": {
                                        "properties": {
                                            "moredata": {
                                                "type": "nested",
                                                "properties": {
                            "key": {"type": "string"},
                            "val": {"type": "string"}


Solution

  • Your query structure is incorrect, it should be something like

    "query": {
      "bool": {
        "must": [{
            "match": {
              "profile.bud.buddies.code": "1"
            }
          },
          {
            "nested": {
              "path": "profile.bud.buddies.moredata",
              "query": {
                "bool": {
                  "must": [{
                      "match": {
                        "profile.bud.buddies.moredata.key": "one"
                      }
                    },
                    {
                      "match": {
                        "profile.bud.buddies.moredata.val": "0"
                      }
                    }
                  ]
                }
              }
            }
            ]
        }
      }
    }
    

    where the nested query is inside of the array of must clauses of the outer bool query. Note that profile.bud.buddies.moredata must be mapped as a nested data type.