为非null和非空创建Elasticsearch curl查询(“”)


74

我如何创建Elasticsearch curl查询以获取不为null且不为空的字段值(“”),

这是mysql查询:

select field1 from mytable where field1!=null and field1!="";

4
所有Elastic问题都应具有您使用的Elastic版本。这是强制性的,因为即使是次要版本也有太多更改
Henley Chiu

Answers:


77

空值和空字符串都不会索引任何值,在这种情况下,您可以使用exists过滤器

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

或结合(例如)在title现场进行全文搜索:

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"
            }
         }
      }
   }
}
'

嗨,只想知道我该怎么做?:)
uttam palkar

1
只是包装多exists在过滤器and过滤elasticsearch.org/guide/reference/query-dsl/and-filter.html
DrTech

无需使用查询来包装过滤器。
WhatIsHeDoing

29
这不会过滤出空字符串。An empty string is a non-null value.- elastic.co/guide/en/elasticsearch/reference/current/...
Luqmaan

注意方便单行格式卷曲-XGET“ 127.0.0.1:9200/test/test/_search?q=_exists_:field1
刘若英Wooller

27

缺少的过滤器包装在Bool过滤器的Must-Not部分中。它将仅返回该字段存在的文档,并且如果将“ null_value”属性设置为true,则显式不为null的值。

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

1
Hurr ...忘记了Exists过滤器。使用DrTech的解决方案,我的方法做起来不太优雅。
Zach

晕!您刚刚结束了大约四个小时的痛苦。谢谢:)
simonmorley13年

这种方法在v1.0.3中对我有效,但在v1.5中不再有效
phirschybar 2015年

@Zach您是否认为可以在任何情况下帮助我stackoverflow.com/questions/33630013/…
BentCoder 2015年

1
这是非常有用的,并且可以作为一个权宜之计,因为退出功能不在我们使用的Elasticsearch版本中。感谢@zach
rubyisbeautiful

27

正如@luqmaan在评论中指出的那样,文档说过滤器exists 不会过滤掉空字符串,因为它们被认为是非null值

因此,在@DrTech的答案中添加有效过滤掉空字符串和空字符串值的方法如下:

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

27

在Elasticsearch 5.6上,我必须使用以下命令过滤掉空字符串:

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

1
遗憾的是,这也是我发现的唯一解决方案...很奇怪,没有简单的查询要说field =''...
danvasiloiu

2
正则表达式不是最佳的性能。检查stackoverflow.com/questions/25561981/…–
danvasiloiu

这是唯一适用于未启用“ fielddata”字段的解决方案,谢谢
Ron Serruya

8

您可以通过布尔查询以及must和must_not的组合来做到这一点,如下所示:

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

我在Kibana中使用Elasticsearch 5.6.5进行了测试。


6

您可以在missing之上使用not过滤器。

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

我能够得到一个缺失的查询,但是我继续在数组上使用“ exists”来查看是否可以找到“ not null”类型的值,并且该值不起作用。这对我来说是正确的解决方案。谢谢!
James Drinkard '16

6

在5.6.5中对我有用的唯一解决方案是bigstone1998的正则表达式答案。尽管出于性能方面考虑,我宁愿不使用正则表达式搜索。我相信其他解决方案不起作用的原因是因为将分析标准字段,因此没有空字符串令牌可否定。因为空字符串被视为非空值,所以存在查询本身也无济于事。

如果您无法更改索引,则正则表达式方法可能是您唯一的选择,但是如果您可以更改索引,则添加关键字子字段将解决此问题。

在索引的映射中:

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

然后,您可以简单地使用查询:

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

注意.keywordmust_not组件中的。


这不适用于type=text字段。但是可以通过扩展ES模式来解决"myfield": { "type": "text", fielddata: true, "fields": { "keyword": { "type": "keyword" } } }
James McGuigan

为什么我们必须使用.keyword?由于must_not完全匹配,它与被分析的字段有什么关系吗?如果是这样,如果我们不使用.keyword,那意味着什么?顺便说一句,.keyword为我使用作品。
卢阳杜

1
@LuyangDu模式定义了两个字段,myfield和myfield.keyword。“ myfield.keyword”字段是一个显式的“ keyword”字段,最多包含256个字符,仅用于精确匹配,而“ myfield”是一个开放文本字段,可以应用标记符和其他处理。因此,这两个字段的工作方式非常不同,只有关键字字段会将空字符串和空字符串都表示为空字符串,从而使您可以否定该字段为空。
LaserJesus

1

我们使用的是Elasticsearch 1.6版,我使用了来自同事的以下查询来说明字段的内容不为null也不为空:

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

您为我节省了很多

1

这是检查多个字段是否存在的查询示例:

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


0

您可以将bool组合查询与must / must_not一起使用,以提供出色的性能并返回该字段不为null且不为空的所有记录。

bool must_not类似于“ NOT AND”,表示字段!=“”,bool必须存在意味着其!= null。

如此有效地启用:其中field1!= null和field1!=“”

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

ElasticSearch版本:

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

0

您需要将bool查询与must / must_not一起使用并且存在

取得地点为空的地方

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

取得不为空的地方

{
  "query": {
    "bool": {
      "must": {
        "exists": {
          "field": "place"
        }
      }
    }
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.