7

我正在使用 ElasticSearch (2.4) 和官方 Python 客户端来执行简单的查询。我的代码:

from elasticsearch import Elasticsearch

es_client = Elasticsearch("localhost:9200")
index = "indexName"
doc_type = "docType"

def search(query, search_size):
    body = {
        "fields": ["title"],
        "size": search_size,
        "query": {
            "query_string": {
                "fields": ["file.content"],
                "query": query
            }
        }
    }
    response = es_client.search(index=index, doc_type=doc_type, body=body)
    return response["hits"]["hits"]

search("python", 10) # Works fine.

问题是当我的查询包含不平衡的括号或方括号时。例如使用search("python {programming", 10)ES 抛出:

elasticsearch.exceptions.RequestError: TransportError(400, u'search_phase_execution_exception', u'Failed to parse query [python {programming}]')

这是 ES 的预期行为吗?它不使用标记器来删除所有这些字符吗?

注意:这也发生在使用 Java 的我身上。

4

4 回答 4

9

我知道我已经迟到了,但我在这里发帖,希望对其他人有所帮助。正如我们从这里的 Elasticsearch 文档中知道的那样, ES 有一些保留字符。

保留字符是:+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /

所以,现在你有两种可能的解决方案来解决它。当我遇到特殊字符问题时,这些对我来说非常有用

解决方案 1:\\

"query": {
    "bool": {
      "must": [
        {
          "match": {
            "country_code.keyword": "IT"
          }
        },
        {
          "query_string": {
            "default_field": "display",
            "query": "Magomadas \\(OR\\), Italy"
          }
        }
      ]
    }
  }

解决方案2:simple_query_string在你的没有改变query但它不支持的情况下使用default_field,所以你可以使用fields

  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "country_code.keyword": "IT"
          }
        },
        {
          "simple_query_string": {
            "fields": ["display"], 
            "query": "Magomadas (OR), Italy"
          }
        }
      ]
    }
  }
于 2018-08-15T06:44:31.933 回答
8

我正在阅读文档,并且query_string更严格。以下是保留字符:+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /

因此,就像 jhilden 所说,我将不得不逃避它们或改用它们simple_query_string

文档:https ://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html

于 2016-11-02T21:42:43.410 回答
5

如上一个答案中所述,某些字符需要转义

+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /

"query": "my:name*&&"应该"query": "my\\:name\\*\\&&"


正则表达式来救援✨</h1>

借助一个简单的正则表达式,我们可以轻松地转义这些字符

Python

import re

def escape_elasticsearch_query(query):
    return re.sub('(\+|\-|\=|&&|\|\||\>|\<|\!|\(|\)|\{|\}|\[|\]|\^|"|~|\*|\?|\:|\\|\/)', '\\\\\\1', query)


query = 'my:name*&&'
escaped_query = escape_elasticsearch_query(query)
print(escaped_query)

输出:

my\:name\*\&&

Javascript

function escapeElasticsearchQuery(query) {
    return query.replace(/(\+|\-|\=|&&|\|\||\>|\<|\!|\(|\)|\{|\}|\[|\]|\^|"|~|\*|\?|\:|\\|\/)/g, '\\$&');
}


let query = 'my:name*&&';
let escapedQuery = escapeElasticsearchQuery(query);
console.log(escapedQuery);

输出:

my\:name\*\&&
于 2019-12-21T13:41:48.500 回答
2

在 ES 中使用query_string时有点奇怪。您需要使用双反斜杠对其进行转义。

以下失败:

GET index1/job/_search
{
  "query": {
    "query_string": {
      "fields": ["jobNumber"],
      "query": "827950 { foo"
    }
  }
}

以下作品

GET index1/job/_search
{
  "query": {
    "query_string": {
      "fields": ["jobNumber"],
      "query": "827950 \\{ foo"
    }
  }
}

注意:如果您使用术语查询或其他类似的东西,则无需转义{

于 2016-11-02T16:54:01.170 回答