119

How can i create Elasticsearch curl query to get the field value which are not null and not empty(""),

Here is the mysql query:

select field1 from mytable where field1!=null and field1!="";
1
  • 6
    all Elastic questions should have the version of Elastic you're using. It's mandatory because even the minor versions have so many changes Commented Jan 19, 2016 at 15:25

13 Answers 13

105

A null value and an empty string both result in no value being indexed, in which case you can use the exists filter

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1'  -d '
{
   "query" : {
      "constant_score" : {
         "filter" : {
            "exists" : {
               "field" : "myfield"
            }
         }
      }
   }
}
'

Or in combination with (eg) a full text search on the title field:

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1'  -d '
{
   "query" : {
      "filtered" : {
         "filter" : {
            "exists" : {
               "field" : "myfield"
            }
         },
         "query" : {
            "match" : {
               "title" : "search keywords"
            }
         }
      }
   }
}
'
Sign up to request clarification or add additional context in comments.

6 Comments

hi, just want to know how can i do for mutiple field. :)
just wrap multiple exists filters in an and filter elasticsearch.org/guide/reference/query-dsl/and-filter.html
There's no need to wrap the filter with a query.
This doesn't filter out empty strings. An empty string is a non-null value. - elastic.co/guide/en/elasticsearch/reference/current/…
note the convenient single line format curl -XGET '127.0.0.1:9200/test/test/_search?q=_exists_:field1'
|
53

As @luqmaan pointed out in the comments, the documentation says that the filter exists doesn't filter out empty strings as they are considered non-null values.

So adding to @DrTech's answer, to effectively filter null and empty string values out, you should use something like this:

{
    "query" : {
        "constant_score" : {
            "filter" : {
                "bool": {
                    "must": {"exists": {"field": "<your_field_name_here>"}},
                    "must_not": {"term": {"<your_field_name_here>": ""}}
                }
            }
        }
    }
}

Comments

41

On elasticsearch 5.6, I have to use command below to filter out empty string:

GET /_search
{
    "query" : {
        "regexp":{
            "<your_field_name_here>": ".+"
        }
    }
}  

3 Comments

sadly yes, that is the only solution i found too... very strange there is no simple query to say field = '' ...
regex is not the best in terms of performance. check stackoverflow.com/questions/25561981/…
This is the only solution that works on fields that don't have "fielddata" enabled, thanks
32

Wrap a Missing Filter in the Must-Not section of a Bool Filter. It will only return documents where the field exists, and if you set the "null_value" property to true, values that are explicitly not null.

{
  "query":{
     "filtered":{
        "query":{
           "match_all":{}
        },
        "filter":{
            "bool":{
              "must":{},
              "should":{},
              "must_not":{
                 "missing":{
                    "field":"field1",
                    "existence":true,
                    "null_value":true
                 }
              }
           }
        }
     }
  }
}

5 Comments

Hurr...forgot about the Exists filter. Use DrTech's solution, mine is a less elegant way to do the same.
Huzzah! You just ended about four hours of misery. Thanks :)
this approach worked for me in v1.0.3, but doesn't work any more in v1.5
@Zach Do you think you could help me with stackoverflow.com/questions/33630013/… by any chance?
this was very helpful and worked well as a stopgap, because exits isn't in the version of elasticsearch we were using. Thanks @zach
9

You can do that with bool query and combination of must and must_not like this:

GET index/_search
{
    "query": {
        "bool": {
            "must": [
                {"exists": {"field": "field1"}}
            ],
            "must_not": [
                {"term": {"field1": ""}}
            ]
        }
    }
}

I tested this with Elasticsearch 5.6.5 in Kibana.

Comments

8

The only solution here that worked for me in 5.6.5 was bigstone1998's regex answer. I'd prefer not to use a regex search though for performance reasons. I believe the reason the other solutions don't work is because a standard field will be analyzed and as a result have no empty string token to negate against. The exists query won't help on it's own either since an empty string is considered non-null.

If you can't change the index the regex approach may be your only option, but if you can change the index then adding a keyword subfield will solve the problem.

In the mappings for the index:

"myfield": {
    "type": "text",
    "fields": {
        "keyword": {
            "ignore_above": 256,
            "type": "keyword"
        }
    }
}

Then you can simply use the query:

{
  "query": {
    "bool": {
      "must": {
        "exists": {
          "field": "myfield"
        }
      },
      "must_not": {
        "term": {
          "myfield.keyword": ""
        }
      }
    }
  }
}

Note the .keyword in the must_not component.

3 Comments

This doesn't work for type=text fields. But can be fixed by extending the ES schema "myfield": { "type": "text", fielddata: true, "fields": { "keyword": { "type": "keyword" } } }
Why do we have to use the .keyword? Does it have anything to do with the analyzed field since must_not is exact match? If so, if we don't use .keyword what does that imply? Btw, using .keyword works for me.
@LuyangDu The schema defines two fields, myfield and myfield.keyword. The "myfield.keyword" field is an explicit "keyword" field which holds a maximum of 256 characters and is used for exact matching only, compared to "myfield" which is an open text field which can have tokenizers and other processing applied. These two fields therefore work very differently and only the keyword field will represent both null and empty strings as an empty string, allowing you to negate against that field being empty.
6

You can use not filter on top of missing.

"query": {
  "filtered": {
     "query": {
        "match_all": {}
     },
     "filter": {
        "not": {
           "filter": {
              "missing": {
                 "field": "searchField"
              }
           }
        }
     }
  }
}

1 Comment

I was able to get a missing query working, but I kept using "exists" on an array to see if I could find a "not null" type value and it wasn't working. This was the correct solution for me. Thanks!
6

Here's the query example to check the existence of multiple fields:

{
  "query": {
    "bool": {
      "filter": [
        {
          "exists": {
            "field": "field_1"
          }
        },
        {
          "exists": {
            "field": "field_2"
          }
        },
        {
          "exists": {
            "field": "field_n"
          }
        }
      ]
    }
  }
}

Comments

2

You can use a bool combination query with must/must_not which gives great performance and returns all records where the field is not null and not empty.

bool must_not is like "NOT AND" which means field!="", bool must exist means its !=null.

so effectively enabling: where field1!=null and field1!=""

GET  IndexName/IndexType/_search
{
    "query": {
        "bool": {
            "must": [{
                "bool": {
                    "must_not": [{
                        "term": { "YourFieldName": ""}
                    }]
                }
            }, {
                "bool": {
                    "must": [{
                      "exists" : { "field" : "YourFieldName" }
                    }]
                }
            }]
        }   
    }
}

ElasticSearch Version:

  "version": {
    "number": "5.6.10",
    "lucene_version": "6.6.1"
  }

Comments

2

ES 7.x

{
  "_source": "field", 
  "query": {
    "bool": {
      "must": [
        {
          "exists": {
            "field":"field"
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "field.keyword": {
              "value": ""
            }
          }
        }
      ]
    }
  }
}

1 Comment

"field": "<theactualfieldname>"
1

We are using Elasticsearch version 1.6 and I used this query from a co-worker to cover not null and not empty for a field:

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "bool": {
          "must": [
            {
              "exists": {
                "field": "myfieldName"
              }
            },
            {
              "not": {
                "filter": {
                  "term": {
                    "myfieldName": ""
                  }
                }
              }
            }
          ]
        }
      }
    }
  }
}

Comments

1

You need to use bool query with must/must_not and exists.

To get where place is null:

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

To get where place is not null:

{
  "query": {
    "bool": {
      "must": {
        "exists": {
          "field": "place"
        }
      }
    }
  }
}

Comments

0
Elastic search Get all record where condition not empty.

const searchQuery = {
      body: {
        query: {
          query_string: {
            default_field: '*.*',
            query: 'feildName: ?*',
          },
        },
      },
      index: 'IndexName'
    };

1 Comment

Please add some description about your answer. Please refer stackoverflow.com/help/how-to-answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.