0

I need to programatically build boolean queries against multiple Solr fields. I thought that the Lucene MultiFieldQueryParser would be a good way to go. This works well except when special characters are involved.

public class QueryParserSpike {

  String userQuery = "(-)-foo";
  String escapedQuery = ClientUtils.escapeQueryChars(userQuery); // \(\-\)\-foo
  Analyzer analyzer = new WhitespaceAnalyzer(Version.LUCENE_43);
  QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_43, new String[]{"a"}, analyzer);

  @Test(expected=ParseException.class)
  public void testNoEscape() throws Exception {
    parser.parse(userQuery); // Throws an exception
  }

  @Test
  public void testEscape() throws Exception {
    Query q = parser.parse(escapedQuery);
    System.out.println(q.toString()); // a:(-)-foo (This can't be parsed by Solr)
  }

  @Test
  public void testDoubleEscape() throws Exception {
    String doubleEscapedQuery = escapedQuery.replaceAll("\\\\", "\\\\\\\\") ;
    Query q = parser.parse(doubleEscapedQuery);
    System.out.println(q.toString()); // (a:\) (a:\-\) (a:\-foo) (This isn't the correct query)
  }

}

What I'm trying to get out of this would be a:\(\-\)\-foo. Is there a Solr class that does something similar? Or is the best option to write something to process the result of the MultiFieldQueryParser myself?

4

1 に答える 1

0

クエリがQuery.toString()メソッドから渡すものは、ユーザーが読み取り可能なクエリでのベスト エフォートです。この場合のように、必ずしも解析可能なクエリではありません。次のようなロジックに頼ることはできませんparser.parse(query.toString())。Lucene Query API は、QueryParser 構文ではまったく表現できない多くのことを表現できます。

クエリをエスケープするために使用する方法はtestEscape()正しく、探しているクエリが得られるはずです。QueryParser.escape(userQuery)生の Lucene メソッドに , を使用することもできます。

于 2013-06-11T20:34:04.410 に答える