LUCENE-2892: Add QueryParser.newFieldQuery

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1069977 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2011-02-11 22:51:53 +00:00
parent f7a130e393
commit 4953202fba
3 changed files with 96 additions and 1 deletions

View File

@ -195,6 +195,10 @@ API Changes
for building top-level norms. If you really need a top-level norms, use
MultiNorms or SlowMultiReaderWrapper. (Robert Muir, Mike Mccandless)
* LUCENE-2892: Add QueryParser.newFieldQuery (called by getFieldQuery by default)
which takes Analyzer as a parameter, for easier customization by subclasses.
(Robert Muir)
New features
* LUCENE-2604: Added RegexpQuery support to QueryParser. Regular expressions

View File

@ -467,7 +467,14 @@ public abstract class QueryParserBase {
/**
* @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

View File

@ -35,6 +35,7 @@ import org.apache.lucene.analysis.TokenStream;
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.WildcardQuery;
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;
@ -1175,5 +1177,87 @@ public class TestQueryParser extends LuceneTestCase {
// 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\""));
}
}