diff --git a/src/java/org/apache/lucene/queryParser/QueryParser.jj b/src/java/org/apache/lucene/queryParser/QueryParser.jj index a1f2fa08e0a..f8973153311 100644 --- a/src/java/org/apache/lucene/queryParser/QueryParser.jj +++ b/src/java/org/apache/lucene/queryParser/QueryParser.jj @@ -288,6 +288,7 @@ PARSER_END(QueryParser) | | (<_TERM_CHAR>)* > | +| )+ > | (<_TERM_CHAR>)* "*" > | (<_TERM_CHAR> | ( [ "*", "?" ] ))* > @@ -375,7 +376,7 @@ Query Clause(String field) : { Query Term(String field) : { - Token term, boost=null; + Token term, boost=null, slop=null; boolean prefix = false; boolean wildcard = false; boolean fuzzy = false; @@ -411,10 +412,18 @@ Query Term(String field) : { rangein); } | term= + [ slop= ] [ boost= ] { q = getFieldQuery(field, analyzer, term.image.substring(1, term.image.length()-1)); + if (slop != null && q instanceof PhraseQuery) { + try { + int s = Float.valueOf(slop.image.substring(1)).intValue(); + ((PhraseQuery) q).setSlop(s); + } + catch (Exception ignored) { } + } } ) { diff --git a/src/java/org/apache/lucene/search/PhraseQuery.java b/src/java/org/apache/lucene/search/PhraseQuery.java index 86ce7fde322..903795d8a0d 100644 --- a/src/java/org/apache/lucene/search/PhraseQuery.java +++ b/src/java/org/apache/lucene/search/PhraseQuery.java @@ -163,6 +163,11 @@ final public class PhraseQuery extends Query { } buffer.append("\""); + if (slop != 0) { + buffer.append("~"); + buffer.append(slop); + } + if (boost != 1.0f) { buffer.append("^"); buffer.append(Float.toString(boost)); diff --git a/src/test/org/apache/lucene/queryParser/TestQueryParser.java b/src/test/org/apache/lucene/queryParser/TestQueryParser.java index c33ac0f20b6..ffc394931ea 100644 --- a/src/test/org/apache/lucene/queryParser/TestQueryParser.java +++ b/src/test/org/apache/lucene/queryParser/TestQueryParser.java @@ -166,6 +166,7 @@ public class TestQueryParser extends TestCase { assertQueryEquals("term^2.0", null, "term^2.0"); assertQueryEquals("term^2", null, "term^2.0"); assertQueryEquals("\"germ term\"^2.0", null, "\"germ term\"^2.0"); + assertQueryEquals("\"term germ\"^2", null, "\"term germ\"^2.0"); assertQueryEquals("(foo OR bar) AND (baz OR boo)", null, "+(foo bar) +(baz boo)"); @@ -184,6 +185,14 @@ public class TestQueryParser extends TestCase { assertQueryEquals(".NET", a, ".NET"); } + public void testSlop() throws Exception { + assertQueryEquals("\"term germ\"~2", null, "\"term germ\"~2"); + assertQueryEquals("\"term germ\"~2 flork", null, "\"term germ\"~2 flork"); + assertQueryEquals("\"term\"~2", null, "term"); + assertQueryEquals("\" \"~2 germ", null, "germ"); + assertQueryEquals("\"term germ\"~2^2", null, "\"term germ\"~2^2.0"); + } + public void testNumber() throws Exception { // The numbers go away because SimpleAnalzyer ignores them assertQueryEquals("3", null, "");