Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 828142) +++ CHANGES.txt (working copy) @@ -39,6 +39,11 @@ settings in StandardAnalyzer to be compatible with the coming Lucene 3.0. (Uwe Schindler) + * LUCENE-2002: Add required Version matchVersion argument when + constructing QueryParser or MultiFieldQueryParser and, default (as + of 2.9) enablePositionIncrements to true to match + StandardAnalyzer's default (Uwe Schindler, Mike McCandless) + Documentation * LUCENE-1955: Fix Hits deprecation notice to point users in right Index: src/test/org/apache/lucene/queryParser/TestQueryParser.java =================================================================== --- src/test/org/apache/lucene/queryParser/TestQueryParser.java (revision 828142) +++ src/test/org/apache/lucene/queryParser/TestQueryParser.java (working copy) @@ -47,6 +47,7 @@ import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; +import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.MultiTermQuery; import org.apache.lucene.search.FuzzyQuery; @@ -60,7 +61,10 @@ import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.WildcardQuery; import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.MockRAMDirectory; import org.apache.lucene.util.LocalizedTestCase; +import org.apache.lucene.util.Version; /** * Tests QueryParser. @@ -1014,4 +1018,24 @@ BooleanQuery.setMaxClauseCount(originalMaxClauses); } + // LUCENE-2002: make sure defaults for StandardAnalyzer's + // enableStopPositionIncr & QueryParser's enablePosIncr + // "match" + public void testPositionIncrements() throws Exception { + Directory dir = new MockRAMDirectory(); + Analyzer a = new StandardAnalyzer(Version.LUCENE_CURRENT); + IndexWriter w = new IndexWriter(dir, a, IndexWriter.MaxFieldLength.UNLIMITED); + Document doc = new Document(); + doc.add(new Field("f", "the wizard of ozzy", Field.Store.NO, Field.Index.ANALYZED)); + w.addDocument(doc); + IndexReader r = w.getReader(); + w.close(); + IndexSearcher s = new IndexSearcher(r); + QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "f", a); + Query q = qp.parse("\"wizard of ozzy\""); + assertEquals(1, s.search(q, 1).totalHits); + r.close(); + dir.close(); + } + } Index: src/java/org/apache/lucene/queryParser/MultiFieldQueryParser.java =================================================================== --- src/java/org/apache/lucene/queryParser/MultiFieldQueryParser.java (revision 828142) +++ src/java/org/apache/lucene/queryParser/MultiFieldQueryParser.java (working copy) @@ -27,6 +27,7 @@ import org.apache.lucene.search.MultiPhraseQuery; import org.apache.lucene.search.PhraseQuery; import org.apache.lucene.search.Query; +import org.apache.lucene.util.Version; /** * A QueryParser which constructs queries to search multiple fields. @@ -64,13 +65,47 @@ * *
In other words, all the query's terms must appear, but it doesn't matter in * what fields they appear.
+ * + * @deprecated Please use {@link #MultiFieldQueryParser(Version, String[], Analyzer, Map)} instead */ public MultiFieldQueryParser(String[] fields, Analyzer analyzer, Map boosts) { - this(fields,analyzer); + this(Version.LUCENE_24, fields, analyzer); this.boosts = boosts; } /** + * Creates a MultiFieldQueryParser. + * Allows passing of a map with term to Boost, and the boost to apply to each term. + * + *It will, when parse(String query)
+ * is called, construct a query like this (assuming the query consists of
+ * two terms and you specify the two fields title and body):
+ * (title:term1 body:term1) (title:term2 body:term2)
+ *
+ *
+ * When setDefaultOperator(AND_OPERATOR) is set, the result will be:
+ * + *
+ * +(title:term1 body:term1) +(title:term2 body:term2)
+ *
+ *
+ * When you pass a boost (title=>5 body=>10) you can get
+ * + *
+ * +(title:term1^5.0 body:term1^10.0) +(title:term2^5.0 body:term2^10.0)
+ *
+ *
+ * In other words, all the query's terms must appear, but it doesn't matter in + * what fields they appear.
+ */ + public MultiFieldQueryParser(Version matchVersion, String[] fields, Analyzer analyzer, Map boosts) { + this(matchVersion, fields, analyzer); + this.boosts = boosts; + } + + /** * Creates a MultiFieldQueryParser. * *It will, when parse(String query) @@ -89,9 +124,35 @@ * *
In other words, all the query's terms must appear, but it doesn't matter in * what fields they appear.
+ * + * @deprecated Please use {@link #MultiFieldQueryParser(Version, String[], Analyzer} instead */ public MultiFieldQueryParser(String[] fields, Analyzer analyzer) { - super(null, analyzer); + this(Version.LUCENE_24, fields, analyzer); + } + + /** + * Creates a MultiFieldQueryParser. + * + *It will, when parse(String query)
+ * is called, construct a query like this (assuming the query consists of
+ * two terms and you specify the two fields title and body):
+ * (title:term1 body:term1) (title:term2 body:term2)
+ *
+ *
+ * When setDefaultOperator(AND_OPERATOR) is set, the result will be:
+ * + *
+ * +(title:term1 body:term1) +(title:term2 body:term2)
+ *
+ *
+ * In other words, all the query's terms must appear, but it doesn't matter in + * what fields they appear.
+ */ + public MultiFieldQueryParser(Version matchVersion, String[] fields, Analyzer analyzer) { + super(matchVersion, null, analyzer); this.fields = fields; } @@ -202,16 +263,40 @@ * @throws ParseException if query parsing fails * @throws IllegalArgumentException if the length of the queries array differs * from the length of the fields array + * @deprecated Use {@link #parse(Version,String[],Analyzer)} instead */ public static Query parse(String[] queries, String[] fields, Analyzer analyzer) throws ParseException { + return parse(Version.LUCENE_24, queries, fields, analyzer); + } + + /** + * Parses a query which searches on the fields specified. + *+ * If x fields are specified, this effectively constructs: + *
+ *
+ * (field1:query1) (field2:query2) (field3:query3)...(fieldx:queryx)
+ *
+ *
+ * @param matchVersion Lucene version to patch; this is passed through to QueryParser.
+ * @param queries Queries strings to parse
+ * @param fields Fields to search on
+ * @param analyzer Analyzer to use
+ * @throws ParseException if query parsing fails
+ * @throws IllegalArgumentException if the length of the queries array differs
+ * from the length of the fields array
+ */
+ public static Query parse(Version matchVersion, String[] queries, String[] fields,
+ Analyzer analyzer) throws ParseException
+ {
if (queries.length != fields.length)
throw new IllegalArgumentException("queries.length != fields.length");
BooleanQuery bQuery = new BooleanQuery();
for (int i = 0; i < fields.length; i++)
{
- QueryParser qp = new QueryParser(fields[i], analyzer);
+ QueryParser qp = new QueryParser(matchVersion, fields[i], analyzer);
Query q = qp.parse(queries[i]);
if (q!=null && // q never null, just being defensive
(!(q instanceof BooleanQuery) || ((BooleanQuery)q).getClauses().length>0)) {
@@ -250,14 +335,51 @@
* @throws ParseException if query parsing fails
* @throws IllegalArgumentException if the length of the fields array differs
* from the length of the flags array
+ * @deprecated Use {@link #parse(Version, String, String[], BooleanClause.Occur[], Analyzer)} instead
*/
public static Query parse(String query, String[] fields,
BooleanClause.Occur[] flags, Analyzer analyzer) throws ParseException {
+ return parse(Version.LUCENE_24, query, fields, flags, analyzer);
+ }
+
+ /**
+ * Parses a query, searching on the fields specified.
+ * Use this if you need to specify certain fields as required,
+ * and others as prohibited.
+ *
+ * Usage:
+ *
+ * String[] fields = {"filename", "contents", "description"};
+ * BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
+ * BooleanClause.Occur.MUST,
+ * BooleanClause.Occur.MUST_NOT};
+ * MultiFieldQueryParser.parse("query", fields, flags, analyzer);
+ *
+ *
+ *+ * The code above would construct a query: + *
+ *
+ * (filename:query) +(contents:query) -(description:query)
+ *
+ *
+ *
+ * @param matchVersion Lucene version to patch; this is passed through to QueryParser.
+ * @param query Query string to parse
+ * @param fields Fields to search on
+ * @param flags Flags describing the fields
+ * @param analyzer Analyzer to use
+ * @throws ParseException if query parsing fails
+ * @throws IllegalArgumentException if the length of the fields array differs
+ * from the length of the flags array
+ */
+ public static Query parse(Version matchVersion, String query, String[] fields,
+ BooleanClause.Occur[] flags, Analyzer analyzer) throws ParseException {
if (fields.length != flags.length)
throw new IllegalArgumentException("fields.length != flags.length");
BooleanQuery bQuery = new BooleanQuery();
for (int i = 0; i < fields.length; i++) {
- QueryParser qp = new QueryParser(fields[i], analyzer);
+ QueryParser qp = new QueryParser(matchVersion, fields[i], analyzer);
Query q = qp.parse(query);
if (q!=null && // q never null, just being defensive
(!(q instanceof BooleanQuery) || ((BooleanQuery)q).getClauses().length>0)) {
@@ -297,16 +419,55 @@
* @throws ParseException if query parsing fails
* @throws IllegalArgumentException if the length of the queries, fields,
* and flags array differ
+ * @deprecated Used {@link #parse(Version, String[], String[], BooleanClause.Occur[], Analyzer)} instead
*/
public static Query parse(String[] queries, String[] fields, BooleanClause.Occur[] flags,
Analyzer analyzer) throws ParseException
{
+ return parse(Version.LUCENE_24, queries, fields, flags, analyzer);
+ }
+
+ /**
+ * Parses a query, searching on the fields specified.
+ * Use this if you need to specify certain fields as required,
+ * and others as prohibited.
+ *
+ * Usage:
+ *
+ * String[] query = {"query1", "query2", "query3"};
+ * String[] fields = {"filename", "contents", "description"};
+ * BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
+ * BooleanClause.Occur.MUST,
+ * BooleanClause.Occur.MUST_NOT};
+ * MultiFieldQueryParser.parse(query, fields, flags, analyzer);
+ *
+ *
+ *+ * The code above would construct a query: + *
+ *
+ * (filename:query1) +(contents:query2) -(description:query3)
+ *
+ *
+ *
+ * @param matchVersion Lucene version to patch; this is passed through to QueryParser.
+ * @param queries Queries string to parse
+ * @param fields Fields to search on
+ * @param flags Flags describing the fields
+ * @param analyzer Analyzer to use
+ * @throws ParseException if query parsing fails
+ * @throws IllegalArgumentException if the length of the queries, fields,
+ * and flags array differ
+ */
+ public static Query parse(Version matchVersion, String[] queries, String[] fields, BooleanClause.Occur[] flags,
+ Analyzer analyzer) throws ParseException
+ {
if (!(queries.length == fields.length && queries.length == flags.length))
throw new IllegalArgumentException("queries, fields, and flags array have have different length");
BooleanQuery bQuery = new BooleanQuery();
for (int i = 0; i < fields.length; i++)
{
- QueryParser qp = new QueryParser(fields[i], analyzer);
+ QueryParser qp = new QueryParser(matchVersion, fields[i], analyzer);
Query q = qp.parse(queries[i]);
if (q!=null && // q never null, just being defensive
(!(q instanceof BooleanQuery) || ((BooleanQuery)q).getClauses().length>0)) {
Index: src/java/org/apache/lucene/queryParser/QueryParser.java
===================================================================
--- src/java/org/apache/lucene/queryParser/QueryParser.java (revision 828142)
+++ src/java/org/apache/lucene/queryParser/QueryParser.java (working copy)
@@ -35,6 +35,7 @@
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.util.Parameter;
+import org.apache.lucene.util.Version;
/**
* This class is generated by JavaCC. The most important method is
@@ -101,6 +102,14 @@
* NOTE: there is a new QueryParser in contrib, which matches * the same syntax as this class, but is more modular, * enabling substantial customization to how a query is created. + * + * + *
NOTE: You must specify the required {@link Version} + * compatibility when creating QueryParser: + *
NOTE: there is a new QueryParser in contrib, which matches * the same syntax as this class, but is more modular, * enabling substantial customization to how a query is created. + * + * + *
NOTE: You must specify the required {@link Version} + * compatibility when creating QueryParser: + *