elasticsearch에 질의할 때, freemarker를 이용하여 아래와 같이 json 질의를 할 수 있다. 


{

  "query": {

    "filtered" : {

      "query" : {

        "query_string" : {

          "query" : "${queryString}"

        }

      }

    }

  }

}



queryString에 사용자가 별의 별 단어를 넣을 수 있는데. 이 때 잘못하면 큰 이상한 문제를 야기할 수 있다.

즉, 사용자가 입력한 모든 내용을 검색해주다가 lucene 문법에 따라 다양한 wildcard, 연산자(and, or, not)로 cpu를 많이 소비할 수 있는데, 이를 escape처리할 수 있다.


처리 방법은 다음과 같다. 


1. lucene 4에서는 QueryParser.escape() 메소드를 이용하여 escape 처리를 한다.

2. and, or, not 제거




참고:

http://lucene.apache.org/core/2_9_4/queryparsersyntax.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html

Reserved charactersedit

If you need to use any of the characters which function as operators in your query itself (and not as operators), then you should escape them with a leading backslash. For instance, to search for (1+1)=2, you would need to write your query as \(1\+1\)\=2.

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


Failing to escape these special characters correctly could lead to a syntax error which prevents your query from running.



lucene4의 QueryParser의 escape()메소드


 
 /**
   * Returns a String where those characters that QueryParser
   * expects to be escaped are escaped by a preceding <code>\</code>.
   */
 
 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();
  }



Posted by '김용환'
,