mirror of https://github.com/apache/lucene.git
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:
parent
f7a130e393
commit
4953202fba
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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\""));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue