Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matching null in should query in Elasticsearch 2.3.0

I have a field gender which can have three values:

  • MALE
  • FEMALE
  • null

The mapping of gender is:

"gender": {
    "type": "string",
    "index": "not_analyzed"
}

To match null I am following this.

I used this query to get the documents with gender as null:

{
    "query": {
        "bool": {
            "must_not": {
                "exists": {
                    "field": "gender"
                }
            }
        }
    }
}

I want to build a should query so that the search results could return any documents having the gender field:

{
  "query": {
    "bool": {
      "should": {
        "bool": {
          "should": [
            {
              "match": {
                "gender": {
                  "query": "MALE",
                  "type": "boolean"
                }
              }
            },
            {
              "match": {
                "gender": {
                  "query": "FEMALE",
                  "type": "boolean"
                }
              }
            }
          ],
          "must_not": {
            "exists": {
              "field": "gender"
            }
          }
        }
      }
    }
  }
}

The query above gives me 0 hits. How should I construct the right query for this?

like image 251
Animesh Pandey Avatar asked Nov 04 '25 15:11

Animesh Pandey


1 Answers

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "gender": {
              "query": "MALE",
              "type": "boolean"
            }
          }
        },
        {
          "match": {
            "gender": {
              "query": "FEMALE",
              "type": "boolean"
            }
          }
        },
        {
          "bool": {
            "must_not": {
              "exists": {
                "field": "gender"
              }
            }
          }
        }
      ]
    }
  }
}

or if I didn't understand the question well and in fact you want to differentiate between gender completely missing from a document or the field being there, but having null, you need something else, that requires changing the mapping slightly:

    "gender": {
      "type": "string",
      "index": "not_analyzed",
      "null_value": "_null_"
    }

And in this case the query is:

  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "gender": {
              "query": "MALE"
            }
          }
        },
        {
          "match": {
            "gender": {
              "query": "FEMALE"
            }
          }
        },
        {
          "term": {
            "gender": "_null_"
          }
        }
      ]
    }
  }

In this case, if you index:

{"index":{}}
{"gender":"MALE"}
{"index":{}}
{"gender":"FEMALE"}
{"index":{}}
{"gender":null}
{"index":{}}
{"gender2":"MALE"}
{"index":{}}
{"gender":"whatever"}

it will give you back:

     {
        "_score": 0.2826735,
        "_source": {
           "gender": "MALE"
        }
     },
     {
        "_score": 0.2826735,
        "_source": {
           "gender": null
        }
     },
     {
        "_score": 0.021688733,
        "_source": {
           "gender": "FEMALE"
        }
     }
like image 169
Andrei Stefan Avatar answered Nov 07 '25 10:11

Andrei Stefan