在elasticsearch上查找具有空字符串值的文档

Pau*_*tor 28 elasticsearch

我一直在尝试使用elasticsearch过滤那些在其主体中包含空字符串的文档.到目前为止,我没有运气.

在我继续之前,我应该提一下,我已经尝试过围绕Interwebz和StackOverflow传播的许多 "解决方案".

所以,下面是我正在尝试运行的查询,后跟其对应项:

{
    "query": {
        "filtered":{
            "filter": {
                "bool": {
                    "must_not": [
                        {
                            "missing":{
                                "field":"_textContent"
                            }
                        }
                    ]
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我也尝试过以下方法:

 {
    "query": {
        "filtered":{
            "filter": {
                "bool": {
                    "must_not": [
                        {
                            "missing":{
                                "field":"_textContent",
                                "existence":true,
                                "null_value":true
                            }
                        }
                    ]
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以下内容:

   {
    "query": {
        "filtered":{
            "filter": {
                    "missing": {"field": "_textContent"}
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以上都没有奏效.当我确定有包含空字符串字段的记录时,我得到一个空结果集.

如果有人能给我任何帮助,我将非常感激.

谢谢!

Dan*_*ery 19

如果您使用的是默认分析器(standard),则无需分析它是否为空字符串.因此,您需要逐字索引字段(未分析).这是一个例子:

添加一个将未标记的字段编入索引的映射,如果您需要索引的字段的标记化副本,则可以使用多字段类型.

PUT http://localhost:9200/test/_mapping/demo
{
  "demo": {
    "properties": {
      "_content": {
        "type": "string",
        "index": "not_analyzed"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

接下来,索引几个文档.

/POST http://localhost:9200/test/demo/1/
{
  "_content": ""
}

/POST http://localhost:9200/test/demo/2
{
  "_content": "some content"
}
Run Code Online (Sandbox Code Playgroud)

执行搜索:

POST http://localhost:9200/test/demo/_search
{
  "query": {
    "filtered": {
      "filter": {
        "term": {
          "_content": ""
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

返回空字符串的文档.

{
    took: 2,
    timed_out: false,
    _shards: {
        total: 5,
        successful: 5,
        failed: 0
    },
    hits: {
        total: 1,
        max_score: 0.30685282,
        hits: [
            {
                _index: test,
                _type: demo,
                _id: 1,
                _score: 0.30685282,
                _source: {
                    _content: ""
                }
            }
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 11

在这里找到解决方案https://github.com/elastic/elasticsearch/issues/7515 它无需重新索引即可工作。

PUT t/t/1
{
  "textContent": ""
}

PUT t/t/2
{
  "textContent": "foo"
}

GET t/t/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "exists": {
            "field": "textContent"
          }
        }
      ],
      "must_not": [
        {
          "wildcard": {
            "textContent": "*"
          }
        }
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


Vir*_*leD 10

即使使用默认分析器,您也可以执行此类搜索:使用脚本过滤器,该过滤器较慢但可以处理空字符串:

curl -XPOST 'http://localhost:9200/test/demo/_search' -d '
{
 "query": {
   "filtered": {
     "filter": {
       "script": {
         "script": "_source._content.length() == 0"
       }
     }
   }
 }
}'
Run Code Online (Sandbox Code Playgroud)

它会将带有空字符串的文档作为_content返回,而不需要特殊的映射

正如@js_gandalf指出的那样,对于ES> 5.0,不推荐使用它.相反,你应该使用:query-> bool-> filter-> script,如https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html


js_*_*alf 7

对于那些使用 Elastic Search 5.2 或更高版本但仍然卡住的人。最简单的方法是使用关键字类型正确地重新索引数据。然后所有对空值的搜索都有效。像这样:

"query": {
    "term": {"MY_FIELD_TO_SEARCH": ""}
}
Run Code Online (Sandbox Code Playgroud)

实际上,当我重新索引数据库并重新运行查询时。它有效=)

问题是我的字段类型是:文本而不是关键字。将索引更改为关键字并重新索引:

curl -X PUT https://username:password@host.io:9200/mycoolindex

curl -X PUT https://user:pass@host.io:9200/mycoolindex/_mapping/mycooltype -d '{
  "properties": {
            "MY_FIELD_TO_SEARCH": {
                    "type": "keyword"
                },
}'

curl -X PUT https://username:password@host.io:9200/_reindex -d '{
 "source": {
   "index": "oldindex"
 },
 "dest": {
    "index": "mycoolindex"
 }
}'
Run Code Online (Sandbox Code Playgroud)

我希望这可以帮助那些像我一样陷入困境的人寻找那些空值。


小智 6

或者使用 lucene 查询字符串语法

q=yourfield.keyword:""

请参阅弹性搜索参考https://www.elastic.co/guide/en/elasticsearch/reference/6.5/query-dsl-query-string-query.html#query-string-syntax