diff --git a/src/java/org/apache/lucene/search/BooleanClause.java b/src/java/org/apache/lucene/search/BooleanClause.java
index 71add59ebac..846725ff093 100644
--- a/src/java/org/apache/lucene/search/BooleanClause.java
+++ b/src/java/org/apache/lucene/search/BooleanClause.java
@@ -18,23 +18,117 @@ package org.apache.lucene.search;
/** A clause in a BooleanQuery. */
public class BooleanClause implements java.io.Serializable {
- /** The query whose matching documents are combined by the boolean query. */
- public Query query;
- /** If true, documents documents which do not
- match this sub-query will not match the boolean query. */
- public boolean required = false;
- /** If true, documents documents which do
- match this sub-query will not match the boolean query. */
- public boolean prohibited = false;
+ public static final class Occur {
+
+ private String name;
+
+ private Occur() {
+ // typesafe enum pattern, no public constructor
+ }
+
+ private Occur(String name) {
+ // typesafe enum pattern, no public constructor
+ this.name = name;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ /** Use this operator for terms that must appear in the matching documents. */
+ public static final Occur MUST = new Occur("MUST");
+ /** Use this operator for terms of which should appear in the
+ * matching documents. For a BooleanQuery with two SHOULD
+ * subqueries, at least one of the queries must appear in the matching documents. */
+ public static final Occur SHOULD = new Occur("SHOULD");
+ /** Use this operator for terms that must not appear in the matching documents.
+ * Note that it is not possible to search for queries that only consist
+ * of a MUST_NOT
query. */
+ public static final Occur MUST_NOT = new Occur("MUST_NOT");
+
+ }
+
+ /** The query whose matching documents are combined by the boolean query.
+ * @deprecated use {@link #setQuery(Query)} instead */
+ public Query query; // TODO: decrease visibility for Lucene 2.0
+
+ /** If true, documents documents which do not
+ match this sub-query will not match the boolean query.
+ @deprecated use {@link #setOccur(BooleanClause.Occur)} instead */
+ public boolean required = false; // TODO: decrease visibility for Lucene 2.0
+
+ /** If true, documents documents which do
+ match this sub-query will not match the boolean query.
+ @deprecated use {@link #setOccur(BooleanClause.Occur)} instead */
+ public boolean prohibited = false; // TODO: decrease visibility for Lucene 2.0
+
+ private Occur occur;
+
/** Constructs a BooleanClause with query q
, required
- r
and prohibited p
. */
+ * r
and prohibited p
.
+ * @deprecated use BooleanClause(Query, Occur) instead
+ *
+ * - For BooleanClause(query, true, false) use BooleanClause(query, BooleanClause.Occur.MUST)
+ *
- For BooleanClause(query, false, false) use BooleanClause(query, BooleanClause.Occur.SHOULD)
+ *
- For BooleanClause(query, false, true) use BooleanClause(query, BooleanClause.Occur.MUST_NOT)
+ *
+ */
public BooleanClause(Query q, boolean r, boolean p) {
+ // TODO: remove for Lucene 2.0
query = q;
required = r;
prohibited = p;
}
+ /** Constructs a BooleanClause.
+ */
+ public BooleanClause(Query query, Occur occur) {
+ this.query = query;
+ this.occur = occur;
+ setFields(occur);
+ }
+
+ public Occur getOccur() {
+ return occur;
+ }
+
+ public void setOccur(Occur occur) {
+ this.occur = occur;
+ setFields(occur);
+ }
+
+ public Query getQuery() {
+ return query;
+ }
+
+ public void setQuery(Query query) {
+ this.query = query;
+ }
+
+ public boolean isProhibited() {
+ return prohibited;
+ }
+
+ public boolean isRequired() {
+ return required;
+ }
+
+ private void setFields(Occur occur) {
+ if (occur == Occur.MUST) {
+ required = true;
+ prohibited = false;
+ } else if (occur == Occur.SHOULD) {
+ required = false;
+ prohibited = false;
+ } else if (occur == Occur.MUST_NOT) {
+ required = false;
+ prohibited = true;
+ } else {
+ throw new IllegalArgumentException("Unknown operator " + occur);
+ }
+ }
+
/** Returns true iff o
is equal to this. */
public boolean equals(Object o) {
if (!(o instanceof BooleanClause))
diff --git a/src/java/org/apache/lucene/search/BooleanQuery.java b/src/java/org/apache/lucene/search/BooleanQuery.java
index 654e5f2e386..6cca7384798 100644
--- a/src/java/org/apache/lucene/search/BooleanQuery.java
+++ b/src/java/org/apache/lucene/search/BooleanQuery.java
@@ -24,7 +24,7 @@ import org.apache.lucene.index.IndexReader;
queries, typically {@link TermQuery}s or {@link PhraseQuery}s.
*/
public class BooleanQuery extends Query {
-
+
/**
* Default value is 1024. Use org.apache.lucene.maxClauseCount
* system property to override.
@@ -65,14 +65,29 @@ public class BooleanQuery extends Query {
* It is an error to specify a clause as both required
and
* prohibited
.
*
- * @see #getMaxClauseCount()
+ * @deprecated use {@link #add(Query, BooleanClause.Occur)} instead:
+ *
+ * - For add(query, true, false) use add(query, BooleanClause.Occur.MUST)
+ *
- For add(query, false, false) use add(query, BooleanClause.Occur.SHOULD)
+ *
- For add(query, false, true) use add(query, BooleanClause.Occur.MUST_NOT)
+ *
*/
public void add(Query query, boolean required, boolean prohibited) {
add(new BooleanClause(query, required, prohibited));
}
/** Adds a clause to a boolean query.
- * @see #getMaxClauseCount()
+ *
+ * @throws TooManyClauses if the new number of clauses exceeds the maximum clause number
+ * @see #getMaxClauseCount()
+ */
+ public void add(Query query, BooleanClause.Occur occur) {
+ add(new BooleanClause(query, occur));
+ }
+
+ /** Adds a clause to a boolean query.
+ * @throws TooManyClauses if the new number of clauses exceeds the maximum clause number
+ * @see #getMaxClauseCount()
*/
public void add(BooleanClause clause) {
if (clauses.size() >= maxClauseCount)
@@ -94,7 +109,7 @@ public class BooleanQuery extends Query {
this.searcher = searcher;
for (int i = 0 ; i < clauses.size(); i++) {
BooleanClause c = (BooleanClause)clauses.elementAt(i);
- weights.add(c.query.createWeight(searcher));
+ weights.add(c.getQuery().createWeight(searcher));
}
}
@@ -106,7 +121,7 @@ public class BooleanQuery extends Query {
for (int i = 0 ; i < weights.size(); i++) {
BooleanClause c = (BooleanClause)clauses.elementAt(i);
Weight w = (Weight)weights.elementAt(i);
- if (!c.prohibited)
+ if (!c.isProhibited())
sum += w.sumOfSquaredWeights(); // sum sub weights
}
@@ -121,7 +136,7 @@ public class BooleanQuery extends Query {
for (int i = 0 ; i < weights.size(); i++) {
BooleanClause c = (BooleanClause)clauses.elementAt(i);
Weight w = (Weight)weights.elementAt(i);
- if (!c.prohibited)
+ if (!c.isProhibited())
w.normalize(norm);
}
}
@@ -137,9 +152,9 @@ public class BooleanQuery extends Query {
boolean noneBoolean = true;
for (int i = 0 ; i < weights.size(); i++) {
BooleanClause c = (BooleanClause)clauses.elementAt(i);
- if (!c.required)
+ if (!c.isRequired())
allRequired = false;
- if (c.query instanceof BooleanQuery)
+ if (c.getQuery() instanceof BooleanQuery)
noneBoolean = false;
}
@@ -164,8 +179,8 @@ public class BooleanQuery extends Query {
Weight w = (Weight)weights.elementAt(i);
Scorer subScorer = w.scorer(reader);
if (subScorer != null)
- result.add(subScorer, c.required, c.prohibited);
- else if (c.required)
+ result.add(subScorer, c.isRequired(), c.isProhibited());
+ else if (c.isRequired())
return null;
}
@@ -183,16 +198,16 @@ public class BooleanQuery extends Query {
BooleanClause c = (BooleanClause)clauses.elementAt(i);
Weight w = (Weight)weights.elementAt(i);
Explanation e = w.explain(reader, doc);
- if (!c.prohibited) maxCoord++;
+ if (!c.isProhibited()) maxCoord++;
if (e.getValue() > 0) {
- if (!c.prohibited) {
+ if (!c.isProhibited()) {
sumExpl.addDetail(e);
sum += e.getValue();
coord++;
} else {
return new Explanation(0.0f, "match prohibited");
}
- } else if (c.required) {
+ } else if (c.isRequired()) {
return new Explanation(0.0f, "match required");
}
}
@@ -223,12 +238,12 @@ public class BooleanQuery extends Query {
public Query rewrite(IndexReader reader) throws IOException {
if (clauses.size() == 1) { // optimize 1-clause queries
BooleanClause c = (BooleanClause)clauses.elementAt(0);
- if (!c.prohibited) { // just return clause
+ if (!c.isProhibited()) { // just return clause
- Query query = c.query.rewrite(reader); // rewrite first
+ Query query = c.getQuery().rewrite(reader); // rewrite first
if (getBoost() != 1.0f) { // incorporate boost
- if (query == c.query) // if rewrite was no-op
+ if (query == c.getQuery()) // if rewrite was no-op
query = (Query)query.clone(); // then clone before boost
query.setBoost(getBoost() * query.getBoost());
}
@@ -240,12 +255,12 @@ public class BooleanQuery extends Query {
BooleanQuery clone = null; // recursively rewrite
for (int i = 0 ; i < clauses.size(); i++) {
BooleanClause c = (BooleanClause)clauses.elementAt(i);
- Query query = c.query.rewrite(reader);
- if (query != c.query) { // clause rewrote: must clone
+ Query query = c.getQuery().rewrite(reader);
+ if (query != c.getQuery()) { // clause rewrote: must clone
if (clone == null)
clone = (BooleanQuery)this.clone();
clone.clauses.setElementAt
- (new BooleanClause(query, c.required, c.prohibited), i);
+ (new BooleanClause(query, c.getOccur()), i);
}
}
if (clone != null) {
@@ -270,18 +285,18 @@ public class BooleanQuery extends Query {
for (int i = 0 ; i < clauses.size(); i++) {
BooleanClause c = (BooleanClause)clauses.elementAt(i);
- if (c.prohibited)
+ if (c.isProhibited())
buffer.append("-");
- else if (c.required)
+ else if (c.isRequired())
buffer.append("+");
- Query subQuery = c.query;
+ Query subQuery = c.getQuery();
if (subQuery instanceof BooleanQuery) { // wrap sub-bools in parens
buffer.append("(");
- buffer.append(c.query.toString(field));
+ buffer.append(c.getQuery().toString(field));
buffer.append(")");
} else
- buffer.append(c.query.toString(field));
+ buffer.append(c.getQuery().toString(field));
if (i != clauses.size()-1)
buffer.append(" ");