我正在使用elasticsearch python client对我们正在托管的elasticsearch实例进行一些查询。
我注意到some characters need to be escaped。具体来说,这些......
+ - && || ! ( ) { } [ ] ^ " ~ * ? : \
除了我已经想到的东西之外,有没有一种干净的方法可以做到这一点?当然,有一种比做更清洁的方式
term
.replace("+", "\+")
.replace("-", "\-")
# ....etc
我希望有一个我可以使用的API调用,但我在文档中找不到一个。这似乎是一个普遍的问题,应该由某人解决。
是否有人知道“正确”的做法?
编辑:我仍然不确定是否有API调用,但我把事情简洁到足以让我感到高兴。
def needs_escaping(character):
escape_chars = {
'\\' : True, '+' : True, '-' : True, '!' : True,
'(' : True, ')' : True, ':' : True, '^' : True,
'[' : True, ']': True, '\"' : True, '{' : True,
'}' : True, '~' : True, '*' : True, '?' : True,
'|' : True, '&' : True, '/' : True
}
return escape_chars.get(character, False)
sanitized = ''
for character in query:
if needs_escaping(character):
sanitized += '\\%s' % character
else:
sanitized += character
答案 0 :(得分:2)
是的,这些字符需要在您要在query_string query中搜索的内容中进行替换。为此(假设您使用的是PyLucene),您应该可以使用QueryParserBase.escape(String)
。
除此之外,您始终可以根据需要调整QueryParserBase.escape
源代码:
public static String escape(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// These characters are part of the query syntax and must be escaped
if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':'
|| c == '^' || c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~'
|| c == '*' || c == '?' || c == '|' || c == '&' || c == '/') {
sb.append('\\');
}
sb.append(c);
}
return sb.toString();
}
答案 1 :(得分:0)
我修改了发现的there代码:
escapeRules = {'+': r'\+',
'-': r'\-',
'&': r'\&',
'|': r'\|',
'!': r'\!',
'(': r'\(',
')': r'\)',
'{': r'\{',
'}': r'\}',
'[': r'\[',
']': r'\]',
'^': r'\^',
'~': r'\~',
'*': r'\*',
'?': r'\?',
':': r'\:',
'"': r'\"',
'\\': r'\\;',
'/': r'\/',
'>': r' ',
'<': r' '}
def escapedSeq(term):
""" Yield the next string based on the
next character (either this char
or escaped version """
for char in term:
if char in escapeRules.keys():
yield escapeRules[char]
else:
yield char
def escapeESArg(term):
""" Apply escaping to the passed in query terms
escaping special characters like : , etc"""
term = term.replace('\\', r'\\') # escape \ first
return "".join([nextStr for nextStr in escapedSeq(term)])
答案 2 :(得分:-1)
直接回答问题,下面是使用re.sub
import re
KIBANA_SPECIAL = '+ - & | ! ( ) { } [ ] ^ " ~ * ? : \\'.split(' ')
re.sub('([{}])'.format('\\'.join(KIBANA_SPECIAL)), r'\\\1', val)
但是,更好的解决方案是正确解析发送到elasticsearch的不良字符:
import six.moves.urllib as urllib
urllib.parse.quote_plus(val)