| Index: lucene/src/test/org/apache/lucene/queryParser/TestQueryParser.java
|
| ===================================================================
|
| --- lucene/src/test/org/apache/lucene/queryParser/TestQueryParser.java (revision 1063677)
|
| +++ lucene/src/test/org/apache/lucene/queryParser/TestQueryParser.java (working copy)
|
| @@ -35,6 +35,7 @@
|
| import org.apache.lucene.analysis.Tokenizer; |
| import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; |
| import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; |
| +import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; |
| import org.apache.lucene.document.DateTools; |
| import org.apache.lucene.document.Document; |
| import org.apache.lucene.document.Field; |
| @@ -58,6 +59,7 @@
|
| import org.apache.lucene.search.BooleanClause.Occur; |
| import org.apache.lucene.store.Directory; |
| import org.apache.lucene.util.LuceneTestCase; |
| +import org.apache.lucene.util.Version; |
| import org.apache.lucene.util.automaton.BasicAutomata; |
| import org.apache.lucene.util.automaton.CharacterRunAutomaton; |
| import org.apache.lucene.util.automaton.RegExp; |
| @@ -1174,5 +1176,87 @@
|
| // expected |
| } |
| } |
| + |
| + /** |
| + * adds synonym of "dog" for "dogs". |
| + */ |
| + private class MockSynonymFilter extends TokenFilter { |
| + CharTermAttribute termAtt = addAttribute(CharTermAttribute.class); |
| + PositionIncrementAttribute posIncAtt = addAttribute(PositionIncrementAttribute.class); |
| + boolean addSynonym = false; |
| + |
| + public MockSynonymFilter(TokenStream input) { |
| + super(input); |
| + } |
| |
| + @Override |
| + public final boolean incrementToken() throws IOException { |
| + if (addSynonym) { // inject our synonym |
| + clearAttributes(); |
| + termAtt.setEmpty().append("dog"); |
| + posIncAtt.setPositionIncrement(0); |
| + addSynonym = false; |
| + return true; |
| + } |
| + |
| + if (input.incrementToken()) { |
| + addSynonym = termAtt.toString().equals("dogs"); |
| + return true; |
| + } else { |
| + return false; |
| + } |
| + } |
| + } |
| + |
| + /** whitespace+lowercase analyzer with synonyms */ |
| + private class Analyzer1 extends Analyzer { |
| + @Override |
| + public TokenStream tokenStream(String fieldName, Reader reader) { |
| + return new MockSynonymFilter(new MockTokenizer(reader, MockTokenizer.WHITESPACE, true)); |
| + } |
| + } |
| + |
| + /** whitespace+lowercase analyzer without synonyms */ |
| + private class Analyzer2 extends Analyzer { |
| + @Override |
| + public TokenStream tokenStream(String fieldName, Reader reader) { |
| + return new MockTokenizer(reader, MockTokenizer.WHITESPACE, true); |
| + } |
| + } |
| + |
| + /** query parser that doesn't expand synonyms when users use double quotes */ |
| + private class SmartQueryParser extends QueryParser { |
| + Analyzer morePrecise = new Analyzer2(); |
| + |
| + public SmartQueryParser() { |
| + super(TEST_VERSION_CURRENT, "field", new Analyzer1()); |
| + } |
| + |
| + @Override |
| + protected Query getFieldQuery(String field, String queryText, boolean quoted) |
| + throws ParseException { |
| + if (quoted) |
| + return newFieldQuery(morePrecise, field, queryText, quoted); |
| + else |
| + return super.getFieldQuery(field, queryText, quoted); |
| + } |
| + } |
| + |
| + public void testNewFieldQuery() throws Exception { |
| + /** ordinary behavior, synonyms form uncoordinated boolean query */ |
| + QueryParser dumb = new QueryParser(TEST_VERSION_CURRENT, "field", new Analyzer1()); |
| + BooleanQuery expanded = new BooleanQuery(true); |
| + expanded.add(new TermQuery(new Term("field", "dogs")), BooleanClause.Occur.SHOULD); |
| + expanded.add(new TermQuery(new Term("field", "dog")), BooleanClause.Occur.SHOULD); |
| + assertEquals(expanded, dumb.parse("\"dogs\"")); |
| + /** even with the phrase operator the behavior is the same */ |
| + assertEquals(expanded, dumb.parse("dogs")); |
| + |
| + /** custom behavior, the synonyms are expanded, unless you use quote operator */ |
| + QueryParser smart = new SmartQueryParser(); |
| + assertEquals(expanded, smart.parse("dogs")); |
| + |
| + Query unexpanded = new TermQuery(new Term("field", "dogs")); |
| + assertEquals(unexpanded, smart.parse("\"dogs\"")); |
| + } |
| } |
| Index: lucene/src/java/org/apache/lucene/queryParser/QueryParserBase.java
|
| ===================================================================
|
| --- lucene/src/java/org/apache/lucene/queryParser/QueryParserBase.java (revision 1063677)
|
| +++ lucene/src/java/org/apache/lucene/queryParser/QueryParserBase.java (working copy)
|
| @@ -467,7 +467,14 @@
|
| /**
|
| * @exception org.apache.lucene.queryParser.ParseException throw in overridden method to disallow
|
| */
|
| - protected Query getFieldQuery(String field, String queryText, boolean quoted) throws ParseException {
|
| + protected Query getFieldQuery(String field, String queryText, boolean quoted) throws ParseException {
|
| + return newFieldQuery(analyzer, field, queryText, quoted);
|
| + }
|
| +
|
| + /**
|
| + * @exception org.apache.lucene.queryParser.ParseException throw in overridden method to disallow
|
| + */
|
| + protected Query newFieldQuery(Analyzer analyzer, String field, String queryText, boolean quoted) throws ParseException {
|
| // Use the analyzer to get all the tokens, and then build a TermQuery,
|
| // PhraseQuery, or nothing based on the term count
|
|
|