ElasticSearch query_string 无法解析包含某些字符的查询
ElasticSearch query_string fails to parse query with some characters
我正在使用 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 时遇到这种情况。
在 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"
}
}
}
注意:如果您使用的是术语查询或其他类似查询,您 不需要 需要转义 {
我正在阅读文档,query_string
更严格。以下是保留字符:+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
所以,就像 jhilden 说的,我必须避开它们或使用 simple_query_string
代替。
文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html
我知道我来晚了,但我在这里发帖,希望对其他人有所帮助。正如我们从 Elasticsearch 文档中了解到的那样 here 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"
}
}
]
}
}
如上一个答案中所述,某些字符需要 转义;
+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
"query": "my:name*&&"
should be "query": "my\:name\*\&&"
正则表达式救援 ✨
借助简单的正则表达式,我们可以轻松转义这些字符
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\*\&&
我正在使用 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 时遇到这种情况。
在 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"
}
}
}
注意:如果您使用的是术语查询或其他类似查询,您 不需要 需要转义 {
我正在阅读文档,query_string
更严格。以下是保留字符:+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
所以,就像 jhilden 说的,我必须避开它们或使用 simple_query_string
代替。
文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html
我知道我来晚了,但我在这里发帖,希望对其他人有所帮助。正如我们从 Elasticsearch 文档中了解到的那样 here 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"
}
}
]
}
}
如上一个答案中所述,某些字符需要 转义;
+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
"query": "my:name*&&"
should be"query": "my\:name\*\&&"
正则表达式救援 ✨
借助简单的正则表达式,我们可以轻松转义这些字符
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\*\&&