Doseikis
Doseikis

Reputation: 69

Elastic combine must and must not

I would like to create a query in elastic where I get all documents that match a value and don't have a specific field: what I'm trying to do is the following:

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "some-field.b": true
                    }
                },
                {
                    "bool": {
                        "must_not": {
                            "exists": {
                                "field": "some-other-field.a"
                            }
                        }
                    }
                }
            ]
        }
    }
}

Even if I change a document in elastic and give a value to the some-other-field.a the query keeps returning me the same number of total hits. Any idea why is this happening?

The only way I found to change this is by adding the a minimum score to the query but I'm not sure I really understand the concept of the score. I would like to get the documents only if both conditions are met.

I noticed one other thing. If I repeat the query while having a minimum score the number of the returned hits varies.

Upvotes: 2

Views: 1072

Answers (2)

Doseikis
Doseikis

Reputation: 69

The final query I needed was the following:

"query": {
    "bool": {
        "must": [
            {
                "match": {
                    "some-field.b": true
                }
            }
        ],
        "must_not": {
            "nested": {
                "path": "some-other-field",
                "query": {
                    "exists": {
                        "field": "some-other-field.a"
                    }
                }
            }
        }
    }
}

It looks like my mistake was the must_not part of the query since the some-other-field was a nested field

Upvotes: 1

Bhavya
Bhavya

Reputation: 16192

Since you have not mentioned anything about your mapping and index data.

Adding a working example with index mapping, index data and search query (considering data to be of nested type as some-other-field.a looks like a nested field)

Index Mapping:

{
  "mappings": {
    "properties": {
      "user": {
        "type": "nested" 
      },
      "qualification": {
        "type": "nested" 
      }
    }
  }
}

Index Data:

{
  "user" : [ 
    {
      "first" : "Bhavya",
      "last" :  "Gupta"
    }
  ]
}

{
  "user" : [ 
    {
      "first" : "Bhavya",
      "last" :  "Gupta"
    }
  ],
  "qualification": [
    {
      "degree": "MTech"
    }
  ]
}

{
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    }
  ],
  "qualification": [
    {
      "degree": "BTech"
    }
  ]
}

Search Query:

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "user",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "user.first": "Bhavya"
                    }
                  }
                ]
              }
            }
          }
        }
      ],
      "must_not": {
        "nested": {
          "path": "qualification",
          "query": {
            "exists": {
              "field": "qualification.degree"
            }
          }
        }
      }
    }
  }
}

Search Result:

"hits": [
      {
        "_index": "stof",
        "_type": "_doc",
        "_id": "3",
        "_score": 0.35667494,
        "_source": {
          "user": [
            {
              "first": "Bhavya",
              "last": "Gupta"
            }
          ]
        }
      }
    ]

Upvotes: 1

Related Questions