Search code examples
elasticsearchelasticsearch-dsl

Elasticsearch: don't return document if any of nested object field matches term value


I struggle with writing a query that should not return a document if any of its nested objects field value matches a term value passed in a query.

Document sample:

 {
      "id": 1,
      "test": "name",
      "rules": [
        {
          "id": 2,
          "name": "rule3",
          "questionDetailConditionalRules": [
            {
              "questionDetailId": 1
            },
            {
              "questionDetailId": 2
            }
          ]
        },
        {
          "id": 3,
          "name": "rule3",
          "questionDetailConditionalRules": [
            {
              "questionDetailId": 4
            },
            {
              "questionDetailId": 5
            }
          ]
        }
      ]
    }

The rule field has nested type

My nested search query is:

{
  "query": {
    "nested": {
      "path": "rules",
      "query": {
        "bool": {
          "must_not": [
            {
              "terms": {
                "rules.questionDetailConditionalRules.questionDetailId": [
                  1
                ]
              }
            }
          ]
        }
      }
    }
  }
}

Expected result: the document should not be returned Actual result: document is returned.

Should I miss anything in my query?


Solution

  • Was able to reproduce your issue and fixed it, please find step by step solution to make it work. you need to move nested inside the must_not block and some modification to your query.

    Index def

    {
        "mappings" :{
            "properties" :{
                "rules" :{
                    "type" : "nested"
                }
            }
        }
    }
    

    Index your sample doc

    {
        "rules": [
            {
                "id": 2,
                "name": "rule3",
                "questionDetailConditionalRules": [
                    {
                        "questionDetailId": 1
                    },
                    {
                        "questionDetailId": 2
                    }
                ]
            },
            {
                "id": 3,
                "name": "rule3",
                "questionDetailConditionalRules": [
                    {
                        "questionDetailId": 4
                    },
                    {
                        "questionDetailId": 5
                    }
                ]
            }
        ]
    }
    

    Search Query

    {
        "query": {
            "bool": {
                "must_not": [
                    {
                        "nested": {
                            "path": "rules",  --> note `nested` is inside the `must_not` block.
                            "query": {
                                "bool": {
                                    "filter": [
                                        {
                                            "term": {
                                                "rules.questionDetailConditionalRules.questionDetailId": 1
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                ]
            }
        }
    }
    

    Search result

    "hits": {
            "total": {
                "value": 0,
                "relation": "eq"
            },
            "max_score": null,
            "hits": []
        }
    

    Note: you can find more info in this link.