I am trying to apply more than one filter on nested object and I want to return only document which has all matching in single object not from multiple object.

Data in elastic search

D1 document
"fields":[
{
    "field_name": "test",
    "field_value": "test",
    "field_id": "123"
},
{
    "field_name": "test1",
    "field_value": "test1",
    "field_id": "1231"
},
{
    "field_name": "test2",
    "field_value": "test2",
    "field_id": "1232"
}]

D2 document
"fields":[
{
    "field_name": "test1",
    "field_value": "testda",
    "field_id": "123a"
},
{
    "field_name": "test1ad",
    "field_value": "test1",
    "field_id": "1231"
},
{
    "field_name": "test2a",
    "field_value": "test2a",
    "field_id": "1231"
}]

Fields is nested object with text & keyword mapping

"fields": {
            "type": "nested",
            "properties": {
              "field_id": {
                "type": "text",
                "fields": {
                  "raw": {
                    "type": "keyword"
                  }
                }
              },
              "field_name": {
                "type": "text",
                "fields": {
                  "raw": {
                    "type": "keyword"
                  }
                }
              },
              "field_value": {
                "type": "text",
                "fields": {
                  "raw": {
                    "type": "keyword"
                  }
                }
              }
            }
          }

This is my elastic search query

GET myindex/_search
{
  "query": {
    "bool": {
      "filter": {
        "nested":{
          "path":"fields",
          "query":{
            "bool":{
              "must":{
                "bool":{
                  "must":[{
                    "match":{
                      "field_id.raw": "1231"
                    }
                  },
                  {
                    "match":{
                      "field_value.raw": "test1"
                    }
                  },
                  {
                    "match":{
                      "field_name.raw": "test1"
                    }
                  }]
                }
              }
            }
          }
        }
      }
    }
  }
}

I am not getting any response. And I want only first document to return as it has matching in same object not document 2 which also have match that is here and there. Thanks in advance ...

1 Answers

0
Nishant Saini On Best Solutions

You have to use fully qualified name in case of nested fields. So instead of field_id.raw it should be fields.field_id.raw. Same goes for other fields as well.

So your query should be:

{
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "fields",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "fields.field_id.raw": "1231"
                    }
                  },
                  {
                    "match": {
                      "fields.field_value.raw": "test1"
                    }
                  },
                  {
                    "match": {
                      "fields.field_name.raw": "test1"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}