2008-11-04 5 views
29

Lucene.net을 사용하고 있지만 .NET과 Java 버전 모두에 대해이 질문에 태그를 지정하고 있습니다. API가 동일하고 두 플랫폼 모두에 솔루션이 있기를 기대하기 때문입니다.Lucene QueryParser를 더 관대하게 만드는 방법은 무엇입니까?

다른 사람들도이 문제를 해결했지만 필자는 훌륭한 토론이나 예제를 찾을 수 없었습니다.

기본적으로 Lucene은 쿼리 구문에 대해 매우 까다 롭습니다.

[ParseException: Cannot parse 'hi there!': Encountered "<EOF>" at line 1, column 9. 
Was expecting one of: 
    "(" ... 
    "*" ... 
    <QUOTED> ... 
    <TERM> ... 
    <PREFIXTERM> ... 
    <WILDTERM> ... 
    "[" ... 
    "{" ... 
    <NUMBER> ... 
    ] 
    Lucene.Net.QueryParsers.QueryParser.Parse(String query) +239 

사용자의 쿼리를 처리 할 때 ParseExceptions을 방지하는 가장 좋은 방법은 무엇입니까 : 예를 들어, 난 그냥 다음과 같은 오류가있어? 그것은 내게 가장 사용할 수있는 검색 인터페이스는 잘못된 쿼리 일지라도 항상 쿼리를 실행하는 것으로 보입니다. 정상적으로

  • 는 지능형보기

    • "청소"쿼리 전에 QueryProcessor
    • 핸들 예외로 보내기에 :

      몇 가능, 보완 전략이 있다는 것을 보인다 사용자에게 오류 메시지가 표시됩니다.

    • 잘못된 비트를 남기고 더 간단한 쿼리를 실행하는 것일 수 있습니다.

이러한 전략을 수행하는 방법에 대한 훌륭한 아이디어가 없습니다. 다른 사람이이 문제를 해결 했습니까? 내가 알지 못하는 "단순"또는 "우아한"파서가 있습니까?

답변

1

나는 당신과 같은 상황에 있습니다.

내가하는 일은 다음과 같습니다. 나는 예외를 잡아 내지 만 오류 만 더 예쁘게 보이도록 만들 수 있습니다. 나는 본문을 바꾸지 않는다.

나는 또한 내가 조금 단순화 한 루씬 구문에 대한 설명에 대한 링크를 제공

:
http://ifdefined.com/btnet/lucene_syntax.html

8

음, 할 수있는 가장 쉬운 방법은 쿼리의 원시 형태에게 기회를 제공하는 것 , 실패하면 다시 청소하십시오.

Query safe_query_parser(QueryParser qp, String raw_query) 
    throws ParseException 
{ 
    Query q; 
    try { 
    q = qp.parse(raw_query); 
    } catch(ParseException e) { 
    q = null; 
    } 
    if(q==null) 
    { 
     String cooked; 
     // consider changing this "" to " " 
     cooked = raw_query.replaceAll("[^\w\s]",""); 
     q = qp.parse(cooked); 
    } 
    return q; 
} 

이 사용자의 쿼리를 실행할 수있는 기회의 원시 형태를 제공하지만, 구문 분석이 실패 할 경우, 우리는 문자, 숫자, 공백 및 밑줄을 제외한 모든 것을 제거; 우리는 다시 시도한다. 우리는 여전히 ParseException을 던질 위험이 있습니다. 그러나 우리는 확률을 대폭 낮추었습니다.

사용자 쿼리를 토큰 화하여 각 토큰을 용어 쿼리로 바꾸고 BooleanQuery와 함께 glomming하는 것도 고려해 볼 수 있습니다. 사용자가 QueryParser의 기능을 활용할 것으로 기대하지 않는다면 가장 좋은 방법 일 것입니다. 당신은 완벽하게 (?) 강력 할 것이고, 사용자는 당신의 분석기를 통해 재미있는 캐릭터가 무엇이든 검색 할 수 있습니다.

1

나는 Lucene.net에 대해 많이 모른다. 일반 Lucene의 경우 책 Lucene in Action을 적극 권장합니다. 현재의 질문은 사용자에 달려 있습니다. 사용자의 쿼리를 제한하기 위해 사용 용이성, 보안 및 성능과 같은 강력한 이유가 있습니다. 이 책은 QueryParser 대신 사용자 정의 파서를 사용하여 쿼리를 구문 분석하는 방법을 보여줍니다.필자는 BooleanQuery에 대한 Jay의 생각을 두 번째로 설명하지만 사용자 정의 파서를 사용하여 더 강력한 쿼리를 작성할 수 있습니다.

42

요 당신이, 당신은 항상이 작업을 수행 할 수 있습니다 사용자가 지금까지 자신의 쿼리에서 고급 구문을 사용하지 않으려면

query = QueryParser.Escape(query) 

처럼 뭔가 쿼리를 살균하여 루씬은 특수 문자를 무시 할 수 있습니다.

사용자가 고급 구문을 사용하기를 원하지만 실수로 더 용서하고 싶다면 ParseException이 발생한 후에 만 ​​위생해야합니다.

+0

을 위해 사용하고있는 코드입니다 내 사용자가 고급 구문을 사용하지 않기 때문에 나는이 솔루션을 사용했다. 감사 ! – Costo

1

모든 Lucene 기능이 필요하지 않은 경우 자체 쿼리 구문 분석기를 작성하여 더 잘 수행 할 수 있습니다. 처음에는 그렇게 복잡하지는 않습니다.

3

참고로 ... 여기에 내가 ParseException가 문제가 있었다 .NET

private Query GetSafeQuery(QueryParser qp, String query) 
    { 
     Query q; 
     try 
     { 
      q = qp.Parse(query); 
     } 

     catch(Lucene.Net.QueryParsers.ParseException e) 
     { 
      q = null; 
     } 

     if(q==null) 
     { 
      string cooked; 

      cooked = Regex.Replace(query, @"[^\w\[email protected]]", " "); 
      q = qp.Parse(cooked); 
     } 

     return q; 
    } 
+0

이 답변은 기본적으로 이전 답변을 복사했습니다. –

+0

@ james.garriss이 스레드는 오래 전에 죽었지만 그걸 말해야 만했다. 비록 당신이 옳을 지 모르지만 그것은 C#에서도 예상대로 작동 할 것입니다. 또한,이 답변에서 정규식 더 완벽합니다. :) –

관련 문제