You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2016/06/21 15:26:30 UTC

lucene-solr:master: LUCENE-7337: empty boolean query now rewrites to MatchNoDocsQuery instead of vice/versa

Repository: lucene-solr
Updated Branches:
  refs/heads/master ceb6e21f8 -> 7b5d7b396


LUCENE-7337: empty boolean query now rewrites to MatchNoDocsQuery instead of vice/versa


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/7b5d7b39
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/7b5d7b39
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/7b5d7b39

Branch: refs/heads/master
Commit: 7b5d7b396254998c0d4d1a6139134639aea1904f
Parents: ceb6e21
Author: Mike McCandless <mi...@apache.org>
Authored: Tue Jun 21 11:26:19 2016 -0400
Committer: Mike McCandless <mi...@apache.org>
Committed: Tue Jun 21 11:26:19 2016 -0400

----------------------------------------------------------------------
 lucene/CHANGES.txt                              |  4 ++
 .../BooleanPerceptronClassifier.java            |  1 -
 .../KNearestNeighborDocumentClassifier.java     |  3 +-
 .../SimpleNaiveBayesDocumentClassifier.java     |  1 -
 .../org/apache/lucene/search/BooleanQuery.java  |  4 ++
 .../apache/lucene/search/MatchNoDocsQuery.java  | 52 +++++++++++++++++---
 .../apache/lucene/search/TestBoostQuery.java    |  4 +-
 .../lucene/search/TestMatchNoDocsQuery.java     |  4 --
 .../search/TestMultiTermQueryRewrites.java      | 12 +++--
 .../org/apache/lucene/search/TestWildcard.java  |  3 +-
 .../lucene/queries/BoostingQueryTest.java       |  4 +-
 .../complexPhrase/ComplexPhraseQueryParser.java |  7 +++
 12 files changed, 76 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7b5d7b39/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index a401964..5239bea 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -62,6 +62,10 @@ Improvements
 * LUCENE-7345: RAMDirectory now enforces write-once files as well
   (Robert Muir, Mike McCandless)
 
+* LUCENE-7337: MatchNoDocsQuery now scores with 0 normalization factor
+  and empty boolean queries now rewrite to MatchNoDocsQuery instead of
+  vice/versa (Jim Ferenczi via Mike McCandless)
+
 Optimizations
 
 * LUCENE-7330: Speed up conjunction queries. (Adrien Grand)

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7b5d7b39/lucene/classification/src/java/org/apache/lucene/classification/BooleanPerceptronClassifier.java
----------------------------------------------------------------------
diff --git a/lucene/classification/src/java/org/apache/lucene/classification/BooleanPerceptronClassifier.java b/lucene/classification/src/java/org/apache/lucene/classification/BooleanPerceptronClassifier.java
index 760e66d..781a14f 100644
--- a/lucene/classification/src/java/org/apache/lucene/classification/BooleanPerceptronClassifier.java
+++ b/lucene/classification/src/java/org/apache/lucene/classification/BooleanPerceptronClassifier.java
@@ -28,7 +28,6 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexableField;
-import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.MultiFields;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.Terms;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7b5d7b39/lucene/classification/src/java/org/apache/lucene/classification/document/KNearestNeighborDocumentClassifier.java
----------------------------------------------------------------------
diff --git a/lucene/classification/src/java/org/apache/lucene/classification/document/KNearestNeighborDocumentClassifier.java b/lucene/classification/src/java/org/apache/lucene/classification/document/KNearestNeighborDocumentClassifier.java
index 248b2eb..342ee08 100644
--- a/lucene/classification/src/java/org/apache/lucene/classification/document/KNearestNeighborDocumentClassifier.java
+++ b/lucene/classification/src/java/org/apache/lucene/classification/document/KNearestNeighborDocumentClassifier.java
@@ -28,7 +28,6 @@ import org.apache.lucene.classification.ClassificationResult;
 import org.apache.lucene.classification.KNearestNeighborClassifier;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
@@ -148,4 +147,4 @@ public class KNearestNeighborDocumentClassifier extends KNearestNeighborClassifi
     }
     return indexSearcher.search(mltQuery.build(), k);
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7b5d7b39/lucene/classification/src/java/org/apache/lucene/classification/document/SimpleNaiveBayesDocumentClassifier.java
----------------------------------------------------------------------
diff --git a/lucene/classification/src/java/org/apache/lucene/classification/document/SimpleNaiveBayesDocumentClassifier.java b/lucene/classification/src/java/org/apache/lucene/classification/document/SimpleNaiveBayesDocumentClassifier.java
index 416d097..21ad7d1 100644
--- a/lucene/classification/src/java/org/apache/lucene/classification/document/SimpleNaiveBayesDocumentClassifier.java
+++ b/lucene/classification/src/java/org/apache/lucene/classification/document/SimpleNaiveBayesDocumentClassifier.java
@@ -34,7 +34,6 @@ import org.apache.lucene.classification.SimpleNaiveBayesClassifier;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexableField;
-import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.MultiFields;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.Terms;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7b5d7b39/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java b/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
index 3371b50..3ac11c8 100644
--- a/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
@@ -228,6 +228,10 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
 
   @Override
   public Query rewrite(IndexReader reader) throws IOException {
+    if (clauses.size() == 0) {
+      return new MatchNoDocsQuery();
+    }
+    
     // optimize 1-clause queries
     if (clauses.size() == 1) {
       BooleanClause c = clauses.get(0);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7b5d7b39/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java b/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
index 77b7952..d373b46 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
@@ -18,22 +18,62 @@ package org.apache.lucene.search;
 
 
 import java.io.IOException;
+import java.util.Set;
 
-import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.Term;
 
 /**
-     * A query that matches no documents.
+ * A query that matches no documents.
  */
+
 public class MatchNoDocsQuery extends Query {
   @Override
-  public Query rewrite(IndexReader reader) throws IOException {
-    // Rewrite to an empty BooleanQuery so no Scorer or Weight is required
-    return new BooleanQuery.Builder().build();
+  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
+    return new Weight(this) {
+      @Override
+      public void extractTerms(Set<Term> terms) {
+      }
+
+      @Override
+      public Explanation explain(LeafReaderContext context, int doc) throws IOException {
+        return Explanation.noMatch("");
+      }
+
+      @Override
+      public Scorer scorer(LeafReaderContext context) throws IOException {
+        return null;
+      }
+
+      @Override
+      public final float getValueForNormalization() throws IOException {
+        return 0;
+      }
+
+      @Override
+      public void normalize(float norm, float boost) {
+      }
+
+      /** Return the normalization factor for this weight. */
+      protected final float queryNorm() {
+        return 0;
+      }
+
+      /** Return the boost for this weight. */
+      protected final float boost() {
+        return 0;
+      }
+
+      /** Return the score produced by this {@link Weight}. */
+      protected final float score() {
+        return 0;
+      }
+    };
   }
 
   @Override
   public String toString(String field) {
-      return "";
+    return "";
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7b5d7b39/lucene/core/src/test/org/apache/lucene/search/TestBoostQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBoostQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestBoostQuery.java
index 427b2fc..e3a37d0 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestBoostQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestBoostQuery.java
@@ -55,8 +55,8 @@ public class TestBoostQuery extends LuceneTestCase {
     IndexSearcher searcher = new IndexSearcher(new MultiReader());
 
     // inner queries are rewritten
-    Query q = new BoostQuery(new MatchNoDocsQuery(), 2);
-    assertEquals(new BoostQuery(new BooleanQuery.Builder().build(), 2), searcher.rewrite(q));
+    Query q = new BoostQuery(new BooleanQuery.Builder().build(), 2);
+    assertEquals(new BoostQuery(new MatchNoDocsQuery(), 2), searcher.rewrite(q));
 
     // boosts are merged
     q = new BoostQuery(new BoostQuery(new MatchAllDocsQuery(), 3), 2);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7b5d7b39/lucene/core/src/test/org/apache/lucene/search/TestMatchNoDocsQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestMatchNoDocsQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestMatchNoDocsQuery.java
index 06d8504..0a97c58 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestMatchNoDocsQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestMatchNoDocsQuery.java
@@ -55,11 +55,7 @@ public class TestMatchNoDocsQuery extends LuceneTestCase {
     hits = is.search(new MatchNoDocsQuery(), 1000).scoreDocs;
     assertEquals(0, hits.length);
 
-    // A MatchNoDocsQuery rewrites to an empty BooleanQuery
     MatchNoDocsQuery mndq = new MatchNoDocsQuery();
-    Query rewritten = mndq.rewrite(ir);
-    assertTrue(rewritten instanceof BooleanQuery);
-    assertEquals(0, ((BooleanQuery) rewritten).clauses().size());
     hits = is.search(mndq, 1000).scoreDocs;
     assertEquals(0, hits.length);
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7b5d7b39/lucene/core/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java b/lucene/core/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java
index 458dd68..44f8d8b 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java
@@ -196,9 +196,15 @@ public class TestMultiTermQueryRewrites extends LuceneTestCase {
     }
     assertEquals("The multi-segment case must produce same rewritten query", q1, q2);
     assertEquals("The multi-segment case with duplicates must produce same rewritten query", q1, q3);
-    checkBooleanQueryBoosts((BooleanQuery) q1);
-    checkBooleanQueryBoosts((BooleanQuery) q2);
-    checkBooleanQueryBoosts((BooleanQuery) q3);
+    if (q1 instanceof MatchNoDocsQuery) {
+      assertTrue(q1 instanceof MatchNoDocsQuery);
+      assertTrue(q3 instanceof MatchNoDocsQuery);
+    } else {
+      checkBooleanQueryBoosts((BooleanQuery) q1);
+      checkBooleanQueryBoosts((BooleanQuery) q2);
+      checkBooleanQueryBoosts((BooleanQuery) q3);
+      assert false;
+    }
   }
   
   public void testBoosts() throws Exception {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7b5d7b39/lucene/core/src/test/org/apache/lucene/search/TestWildcard.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestWildcard.java b/lucene/core/src/test/org/apache/lucene/search/TestWildcard.java
index 3d77bc7..4255d7c 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestWildcard.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestWildcard.java
@@ -96,8 +96,7 @@ public class TestWildcard extends LuceneTestCase {
     wq.setRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_REWRITE);
     assertMatches(searcher, wq, 0);
     Query q = searcher.rewrite(wq);
-    assertTrue(q instanceof BooleanQuery);
-    assertEquals(0, ((BooleanQuery) q).clauses().size());
+    assertTrue(q instanceof MatchNoDocsQuery);
     reader.close();
     indexStore.close();
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7b5d7b39/lucene/queries/src/test/org/apache/lucene/queries/BoostingQueryTest.java
----------------------------------------------------------------------
diff --git a/lucene/queries/src/test/org/apache/lucene/queries/BoostingQueryTest.java b/lucene/queries/src/test/org/apache/lucene/queries/BoostingQueryTest.java
index 939af74..a224bda 100644
--- a/lucene/queries/src/test/org/apache/lucene/queries/BoostingQueryTest.java
+++ b/lucene/queries/src/test/org/apache/lucene/queries/BoostingQueryTest.java
@@ -46,9 +46,9 @@ public class BoostingQueryTest extends LuceneTestCase {
 
   public void testRewrite() throws IOException {
     IndexReader reader = new MultiReader();
-    BoostingQuery q = new BoostingQuery(new MatchNoDocsQuery(), new MatchAllDocsQuery(), 3);
+    BoostingQuery q = new BoostingQuery(new BooleanQuery.Builder().build(), new MatchAllDocsQuery(), 3);
     Query rewritten = new IndexSearcher(reader).rewrite(q);
-    Query expectedRewritten = new BoostingQuery(new BooleanQuery.Builder().build(), new MatchAllDocsQuery(), 3);
+    Query expectedRewritten = new BoostingQuery(new MatchNoDocsQuery(), new MatchAllDocsQuery(), 3);
     assertEquals(expectedRewritten, rewritten);
     assertSame(rewritten, rewritten.rewrite(reader));
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7b5d7b39/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java
index 2a7f8a8..ac808d7 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java
@@ -31,6 +31,7 @@ import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.BoostQuery;
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.MatchNoDocsQuery;
 import org.apache.lucene.search.MultiTermQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TermQuery;
@@ -295,6 +296,12 @@ public class ComplexPhraseQueryParser extends QueryParser {
             allSpanClauses[i] = new SpanTermQuery(new Term(field,
                 "Dummy clause because no terms found - must match nothing"));
           }
+        } else if (qc instanceof MatchNoDocsQuery) {
+          // Insert fake term e.g. phrase query was for "Fred Smithe*" and
+          // there were no "Smithe*" terms - need to
+          // prevent match on just "Fred".
+          allSpanClauses[i] = new SpanTermQuery(new Term(field,
+                                                         "Dummy clause because no terms found - must match nothing"));
         } else {
           if (qc instanceof TermQuery) {
             TermQuery tq = (TermQuery) qc;