【问题标题】:Escaping special characters in elasticsearch在elasticsearch中转义特殊字符
【发布时间】:2017-03-06 11:35:47
【问题描述】:

我正在使用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 

【问题讨论】:

标签: python elasticsearch replace lucene escaping


【解决方案1】:

直接回答问题,下面是使用re.sub的更干净的python解决方案

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)

【讨论】:

  • 请提供更多详细信息
【解决方案2】:

我修改了我找到的这段代码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)])

【讨论】:

    【解决方案3】:

    是的,这些字符需要在您要在 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();
    }
    

    【讨论】:

    • java 代码帮了大忙。我将编辑以包含我的 python 答案,但这是在正确的轨道上。
    • 这个条件什么时候成立? ``` c == '\"' ```
    • @SavvaSergey 虽然在这种情况下双引号的转义不是绝对必要的,但转义的双引号仍将被视为普通的单字符双引号。
    猜你喜欢
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    • 2012-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多