You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2017/12/07 09:50:19 UTC

[2/7] lucene-solr:master: LUCENE-4100: Faster disjunctions when the hit count is not needed.

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
index 52381e1..83a471f 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
@@ -25,6 +25,7 @@ import org.apache.lucene.search.ConstantScoreScorer;
 import org.apache.lucene.search.ConstantScoreWeight;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.spatial3d.geom.BasePlanetObject;
@@ -60,7 +61,7 @@ final class PointInGeo3DShapeQuery extends Query {
   }
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
 
     // I don't use RandomAccessWeight here: it's no good to approximate with "match all docs"; this is an inverted structure and should be
     // used in the first pass:

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
index 295d63b..e05ce76 100644
--- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
@@ -55,6 +55,7 @@ import org.apache.lucene.index.SegmentWriteState;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.SimpleCollector;
 import org.apache.lucene.spatial3d.geom.GeoArea;
 import org.apache.lucene.spatial3d.geom.GeoAreaFactory;
@@ -814,8 +815,8 @@ public class TestGeo3DPoint extends LuceneTestCase {
           private int docBase;
 
           @Override
-          public boolean needsScores() {
-            return false;
+          public ScoreMode scoreMode() {
+            return ScoreMode.COMPLETE_NO_SCORES;
           }
 
           @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java
----------------------------------------------------------------------
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java
index 4a29f24..467708a 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java
@@ -23,6 +23,7 @@ import java.util.Map;
 import java.util.TreeSet;
 
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
@@ -164,8 +165,8 @@ public class ContextQuery extends CompletionQuery {
   }
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
-    final CompletionWeight innerWeight = ((CompletionWeight) innerQuery.createWeight(searcher, needsScores, boost));
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
+    final CompletionWeight innerWeight = ((CompletionWeight) innerQuery.createWeight(searcher, scoreMode, boost));
     // if separators are preserved the fst contains a SEP_LABEL
     // behind each gap. To have a matching automaton, we need to
     // include the SEP_LABEL in the query as well

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/FuzzyCompletionQuery.java
----------------------------------------------------------------------
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/FuzzyCompletionQuery.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/FuzzyCompletionQuery.java
index be3aa95..b243f4e 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/FuzzyCompletionQuery.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/FuzzyCompletionQuery.java
@@ -25,6 +25,7 @@ import java.util.Set;
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.search.suggest.BitsProducer;
 import org.apache.lucene.util.IntsRef;
@@ -142,7 +143,7 @@ public class FuzzyCompletionQuery extends PrefixCompletionQuery {
   }
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
     CompletionTokenStream stream = (CompletionTokenStream) analyzer.tokenStream(getField(), getTerm().text());
     Set<IntsRef> refs = new HashSet<>();
     Automaton automaton = toLevenshteinAutomata(stream.toAutomaton(unicodeAware), refs);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java
----------------------------------------------------------------------
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java
index dbc9298..7bb75e9 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.search.suggest.BitsProducer;
 
@@ -66,7 +67,7 @@ public class PrefixCompletionQuery extends CompletionQuery {
   }
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
     CompletionTokenStream stream = (CompletionTokenStream) analyzer.tokenStream(getField(), getTerm().text());
     return new CompletionWeight(this, stream.toAutomaton());
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java
----------------------------------------------------------------------
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java
index 71b4b67..b53ac34 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.search.suggest.BitsProducer;
 import org.apache.lucene.util.automaton.Operations;
@@ -88,7 +89,7 @@ public class RegexCompletionQuery extends CompletionQuery {
   }
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
     return new CompletionWeight(this, new RegExp(getTerm().text(), flags).toAutomaton(maxDeterminizedStates));
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/SuggestIndexSearcher.java
----------------------------------------------------------------------
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/SuggestIndexSearcher.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/SuggestIndexSearcher.java
index 5f65906..8d8d550 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/SuggestIndexSearcher.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/SuggestIndexSearcher.java
@@ -70,7 +70,7 @@ public class SuggestIndexSearcher extends IndexSearcher {
     // TODO use IndexSearcher.rewrite instead
     // have to implement equals() and hashCode() in CompletionQuerys and co
     query = (CompletionQuery) query.rewrite(getIndexReader());
-    Weight weight = query.createWeight(this, collector.needsScores(), 1f);
+    Weight weight = query.createWeight(this, collector.scoreMode(), 1f);
     for (LeafReaderContext context : getIndexReader().leaves()) {
       BulkScorer scorer = weight.bulkScorer(context);
       if (scorer != null) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/TopSuggestDocsCollector.java
----------------------------------------------------------------------
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/TopSuggestDocsCollector.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/TopSuggestDocsCollector.java
index 3336896..90db227 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/TopSuggestDocsCollector.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/TopSuggestDocsCollector.java
@@ -25,6 +25,7 @@ import java.util.List;
 import org.apache.lucene.analysis.CharArraySet;
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.search.CollectionTerminatedException;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.SimpleCollector;
 
 import static org.apache.lucene.search.suggest.document.TopSuggestDocs.SuggestScoreDoc;
@@ -195,7 +196,7 @@ public class TopSuggestDocsCollector extends SimpleCollector {
    * Ignored
    */
   @Override
-  public boolean needsScores() {
-    return true;
+  public ScoreMode scoreMode() {
+    return ScoreMode.COMPLETE;
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/geo/BaseGeoPointTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/geo/BaseGeoPointTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/geo/BaseGeoPointTestCase.java
index 562db8f..6b39930 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/geo/BaseGeoPointTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/geo/BaseGeoPointTestCase.java
@@ -54,6 +54,7 @@ import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchNoDocsQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.SimpleCollector;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.TopDocs;
@@ -564,8 +565,8 @@ public abstract class BaseGeoPointTestCase extends LuceneTestCase {
           private int docBase;
 
           @Override
-          public boolean needsScores() {
-            return false;
+          public ScoreMode scoreMode() {
+            return ScoreMode.COMPLETE_NO_SCORES;
           }
 
           @Override
@@ -824,8 +825,8 @@ public abstract class BaseGeoPointTestCase extends LuceneTestCase {
           private int docBase;
 
           @Override
-          public boolean needsScores() {
-            return false;
+          public ScoreMode scoreMode() {
+            return ScoreMode.COMPLETE_NO_SCORES;
           }
 
           @Override
@@ -963,8 +964,8 @@ public abstract class BaseGeoPointTestCase extends LuceneTestCase {
           private int docBase;
 
           @Override
-          public boolean needsScores() {
-            return false;
+          public ScoreMode scoreMode() {
+            return ScoreMode.COMPLETE_NO_SCORES;
           }
 
           @Override
@@ -1095,8 +1096,8 @@ public abstract class BaseGeoPointTestCase extends LuceneTestCase {
           private int docBase;
 
           @Override
-          public boolean needsScores() {
-            return false;
+          public ScoreMode scoreMode() {
+            return ScoreMode.COMPLETE_NO_SCORES;
           }
 
           @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/AssertingBulkScorer.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingBulkScorer.java b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingBulkScorer.java
index 6fcc563..ed25878 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingBulkScorer.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingBulkScorer.java
@@ -27,22 +27,24 @@ import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
 /** Wraps a Scorer with additional checks */
 final class AssertingBulkScorer extends BulkScorer {
 
-  public static BulkScorer wrap(Random random, BulkScorer other, int maxDoc) {
+  public static BulkScorer wrap(Random random, BulkScorer other, int maxDoc, ScoreMode scoreMode) {
     if (other == null || other instanceof AssertingBulkScorer) {
       return other;
     }
-    return new AssertingBulkScorer(random, other, maxDoc);
+    return new AssertingBulkScorer(random, other, maxDoc, scoreMode);
   }
 
   final Random random;
   final BulkScorer in;
   final int maxDoc;
+  final ScoreMode scoreMode;
   int max = 0;
 
-  private AssertingBulkScorer(Random random, BulkScorer in, int maxDoc) {
+  private AssertingBulkScorer(Random random, BulkScorer in, int maxDoc, ScoreMode scoreMode) {
     this.random = random;
     this.in = in;
     this.maxDoc = maxDoc;
+    this.scoreMode = scoreMode;
   }
 
   public BulkScorer getIn() {
@@ -57,7 +59,7 @@ final class AssertingBulkScorer extends BulkScorer {
   @Override
   public void score(LeafCollector collector, Bits acceptDocs) throws IOException {
     assert max == 0;
-    collector = new AssertingLeafCollector(random, collector, 0, PostingsEnum.NO_MORE_DOCS);
+    collector = new AssertingLeafCollector(random, collector, 0, PostingsEnum.NO_MORE_DOCS, scoreMode);
     if (random.nextBoolean()) {
       try {
         final int next = score(collector, acceptDocs, 0, PostingsEnum.NO_MORE_DOCS);
@@ -75,7 +77,7 @@ final class AssertingBulkScorer extends BulkScorer {
     assert min >= this.max: "Scoring backward: min=" + min + " while previous max was max=" + this.max;
     assert min <= max : "max must be greater than min, got min=" + min + ", and max=" + max;
     this.max = max;
-    collector = new AssertingLeafCollector(random, collector, min, max);
+    collector = new AssertingLeafCollector(random, collector, min, max, scoreMode);
     final int next = in.score(collector, acceptDocs, min, max);
     assert next >= max;
     if (max >= maxDoc || next >= maxDoc) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/AssertingCollector.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingCollector.java b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingCollector.java
index 22cd686..a3bf87b 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingCollector.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingCollector.java
@@ -46,7 +46,7 @@ class AssertingCollector extends FilterCollector {
   public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException {
     final LeafCollector in = super.getLeafCollector(context);
     final int docBase = context.docBase;
-    return new AssertingLeafCollector(random, in, 0, DocIdSetIterator.NO_MORE_DOCS) {
+    return new AssertingLeafCollector(random, in, 0, DocIdSetIterator.NO_MORE_DOCS, scoreMode()) {
       @Override
       public void collect(int doc) throws IOException {
         // check that documents are scored in order globally,

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/AssertingIndexSearcher.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingIndexSearcher.java b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingIndexSearcher.java
index a9a7321..2a6376d 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingIndexSearcher.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingIndexSearcher.java
@@ -52,9 +52,9 @@ public class AssertingIndexSearcher extends IndexSearcher {
   }
 
   @Override
-  public Weight createWeight(Query query, boolean needsScores, float boost) throws IOException {
+  public Weight createWeight(Query query, ScoreMode scoreMode, float boost) throws IOException {
     // this adds assertions to the inner weights/scorers too
-    return new AssertingWeight(random, super.createWeight(query, needsScores, boost), needsScores);
+    return new AssertingWeight(random, super.createWeight(query, scoreMode, boost), scoreMode);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/AssertingLeafCollector.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingLeafCollector.java b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingLeafCollector.java
index 2b28800..0afece8 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingLeafCollector.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingLeafCollector.java
@@ -26,21 +26,23 @@ class AssertingLeafCollector extends FilterLeafCollector {
   private final Random random;
   private final int min;
   private final int max;
+  private final ScoreMode scoreMode;
 
   private Scorer scorer;
   private int lastCollected = -1;
 
-  AssertingLeafCollector(Random random, LeafCollector collector, int min, int max) {
+  AssertingLeafCollector(Random random, LeafCollector collector, int min, int max, ScoreMode scoreMode) {
     super(collector);
     this.random = random;
     this.min = min;
     this.max = max;
+    this.scoreMode = scoreMode;
   }
 
   @Override
   public void setScorer(Scorer scorer) throws IOException {
     this.scorer = scorer;
-    super.setScorer(AssertingScorer.wrap(random, scorer, true));
+    super.setScorer(AssertingScorer.wrap(random, scorer, scoreMode));
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java
index d8fde24..b3d2f81 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java
@@ -39,9 +39,9 @@ public final class AssertingQuery extends Query {
   }
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
     assert boost >= 0;
-    return new AssertingWeight(new Random(random.nextLong()), in.createWeight(searcher, needsScores, boost), needsScores);
+    return new AssertingWeight(new Random(random.nextLong()), in.createWeight(searcher, scoreMode, boost), scoreMode);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java
index f4e523a..b6062a2 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java
@@ -26,25 +26,26 @@ public class AssertingScorer extends Scorer {
 
   static enum IteratorState { START, APPROXIMATING, ITERATING, FINISHED };
 
-  public static Scorer wrap(Random random, Scorer other, boolean canScore) {
+  public static Scorer wrap(Random random, Scorer other, ScoreMode scoreMode) {
     if (other == null) {
       return null;
     }
-    return new AssertingScorer(random, other, canScore);
+    return new AssertingScorer(random, other, scoreMode);
   }
 
   final Random random;
   final Scorer in;
-  final boolean needsScores;
+  final ScoreMode scoreMode;
 
   IteratorState state = IteratorState.START;
   int doc;
+  float minCompetitiveScore = 0;
 
-  private AssertingScorer(Random random, Scorer in, boolean needsScores) {
+  private AssertingScorer(Random random, Scorer in, ScoreMode scoreMode) {
     super(in.weight);
     this.random = random;
     this.in = in;
-    this.needsScores = needsScores;
+    this.scoreMode = scoreMode;
     this.doc = in.docID();
   }
 
@@ -64,11 +65,28 @@ public class AssertingScorer extends Scorer {
   }
 
   @Override
+  public void setMinCompetitiveScore(float score) {
+    assert scoreMode == ScoreMode.TOP_SCORES;
+    assert Float.isNaN(score) == false;
+    assert score >= minCompetitiveScore;
+    in.setMinCompetitiveScore(score);
+    minCompetitiveScore = score;
+  }
+
+  @Override
+  public float maxScore() {
+    float maxScore = in.maxScore();
+    assert Float.isNaN(maxScore) == false;
+    return maxScore;
+  }
+
+  @Override
   public float score() throws IOException {
-    assert needsScores;
+    assert scoreMode.needsScores();
     assert iterating();
     final float score = in.score();
     assert !Float.isNaN(score) : "NaN score for in="+in;
+    assert score <= maxScore();
     assert Float.compare(score, 0f) >= 0 : score;
     return score;
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/AssertingWeight.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingWeight.java b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingWeight.java
index b98e6a1..8e3a29f 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingWeight.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingWeight.java
@@ -23,12 +23,12 @@ import org.apache.lucene.index.LeafReaderContext;
 class AssertingWeight extends FilterWeight {
 
   final Random random;
-  final boolean needsScores;
+  final ScoreMode scoreMode;
 
-  AssertingWeight(Random random, Weight in, boolean needsScores) {
+  AssertingWeight(Random random, Weight in, ScoreMode scoreMode) {
     super(in);
     this.random = random;
-    this.needsScores = needsScores;
+    this.scoreMode = scoreMode;
   }
 
   @Override
@@ -36,7 +36,7 @@ class AssertingWeight extends FilterWeight {
     if (random.nextBoolean()) {
       final Scorer inScorer = in.scorer(context);
       assert inScorer == null || inScorer.docID() == -1;
-      return AssertingScorer.wrap(new Random(random.nextLong()), inScorer, needsScores);
+      return AssertingScorer.wrap(new Random(random.nextLong()), inScorer, scoreMode);
     } else {
       final ScorerSupplier scorerSupplier = scorerSupplier(context);
       if (scorerSupplier == null) {
@@ -63,7 +63,7 @@ class AssertingWeight extends FilterWeight {
         assert getCalled == false;
         getCalled = true;
         assert leadCost >= 0 : leadCost;
-        return AssertingScorer.wrap(new Random(random.nextLong()), inScorerSupplier.get(leadCost), needsScores);
+        return AssertingScorer.wrap(new Random(random.nextLong()), inScorerSupplier.get(leadCost), scoreMode);
       }
 
       @Override
@@ -82,6 +82,6 @@ class AssertingWeight extends FilterWeight {
       return null;
     }
 
-    return AssertingBulkScorer.wrap(new Random(random.nextLong()), inScorer, context.reader().maxDoc());
+    return AssertingBulkScorer.wrap(new Random(random.nextLong()), inScorer, context.reader().maxDoc(), scoreMode);
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java
index 23071a1..9d75f16 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java
@@ -253,7 +253,7 @@ public abstract class BaseRangeFieldQueryTestCase extends LuceneTestCase {
         }
 
         @Override
-        public boolean needsScores() { return false; }
+        public ScoreMode scoreMode() { return ScoreMode.COMPLETE_NO_SCORES; }
       });
 
       NumericDocValues docIDToID = MultiDocValues.getNumericValues(r, "id");

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/BulkScorerWrapperScorer.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/BulkScorerWrapperScorer.java b/lucene/test-framework/src/java/org/apache/lucene/search/BulkScorerWrapperScorer.java
index db11318..db1de52 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/BulkScorerWrapperScorer.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/BulkScorerWrapperScorer.java
@@ -70,6 +70,11 @@ public class BulkScorerWrapperScorer extends Scorer {
   }
 
   @Override
+  public float maxScore() {
+    return Float.POSITIVE_INFINITY;
+  }
+
+  @Override
   public int docID() {
     return doc;
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java b/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java
index 38fbcfc..2797427 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java
@@ -126,8 +126,8 @@ public class CheckHits {
     }
     
     @Override
-    public boolean needsScores() {
-      return false;
+    public ScoreMode scoreMode() {
+      return ScoreMode.COMPLETE_NO_SCORES;
     }
   }
 
@@ -515,8 +515,8 @@ public class CheckHits {
     }
     
     @Override
-    public boolean needsScores() {
-      return true;
+    public ScoreMode scoreMode() {
+      return ScoreMode.COMPLETE;
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java b/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java
index cb2c984..1773977 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java
@@ -309,7 +309,7 @@ public class QueryUtils {
             lastDoc[0] = doc;
             try {
               if (scorer == null) {
-                Weight w = s.createNormalizedWeight(q, true);
+                Weight w = s.createNormalizedWeight(q, ScoreMode.COMPLETE);
                 LeafReaderContext context = readerContextArray.get(leafPtr);
                 scorer = w.scorer(context);
                 iterator = scorer.iterator();
@@ -362,8 +362,8 @@ public class QueryUtils {
           }
 
           @Override
-          public boolean needsScores() {
-            return true;
+          public ScoreMode scoreMode() {
+            return ScoreMode.COMPLETE;
           }
 
           @Override
@@ -374,7 +374,7 @@ public class QueryUtils {
               final LeafReader previousReader = lastReader[0];
               IndexSearcher indexSearcher = LuceneTestCase.newSearcher(previousReader, false);
               indexSearcher.setSimilarity(s.getSimilarity(true));
-              Weight w = indexSearcher.createNormalizedWeight(q, true);
+              Weight w = indexSearcher.createNormalizedWeight(q, ScoreMode.COMPLETE);
               LeafReaderContext ctx = (LeafReaderContext)indexSearcher.getTopReaderContext();
               Scorer scorer = w.scorer(ctx);
               if (scorer != null) {
@@ -404,7 +404,7 @@ public class QueryUtils {
           final LeafReader previousReader = lastReader[0];
           IndexSearcher indexSearcher = LuceneTestCase.newSearcher(previousReader, false);
           indexSearcher.setSimilarity(s.getSimilarity(true));
-          Weight w = indexSearcher.createNormalizedWeight(q, true);
+          Weight w = indexSearcher.createNormalizedWeight(q, ScoreMode.COMPLETE);
           LeafReaderContext ctx = previousReader.getContext();
           Scorer scorer = w.scorer(ctx);
           if (scorer != null) {
@@ -443,7 +443,7 @@ public class QueryUtils {
         try {
           long startMS = System.currentTimeMillis();
           for (int i=lastDoc[0]+1; i<=doc; i++) {
-            Weight w = s.createNormalizedWeight(q, true);
+            Weight w = s.createNormalizedWeight(q, ScoreMode.COMPLETE);
             Scorer scorer = w.scorer(context.get(leafPtr));
             Assert.assertTrue("query collected "+doc+" but advance("+i+") says no more docs!",scorer.iterator().advance(i) != DocIdSetIterator.NO_MORE_DOCS);
             Assert.assertEquals("query collected "+doc+" but advance("+i+") got to "+scorer.docID(),doc,scorer.docID());
@@ -464,8 +464,8 @@ public class QueryUtils {
       }
 
       @Override
-      public boolean needsScores() {
-        return true;
+      public ScoreMode scoreMode() {
+        return ScoreMode.COMPLETE;
       }
 
       @Override
@@ -476,7 +476,7 @@ public class QueryUtils {
           final LeafReader previousReader = lastReader[0];
           IndexSearcher indexSearcher = LuceneTestCase.newSearcher(previousReader, false);
           indexSearcher.setSimilarity(s.getSimilarity(true));
-          Weight w = indexSearcher.createNormalizedWeight(q, true);
+          Weight w = indexSearcher.createNormalizedWeight(q, ScoreMode.COMPLETE);
           Scorer scorer = w.scorer((LeafReaderContext)indexSearcher.getTopReaderContext());
           if (scorer != null) {
             DocIdSetIterator iterator = scorer.iterator();
@@ -504,7 +504,7 @@ public class QueryUtils {
       final LeafReader previousReader = lastReader[0];
       IndexSearcher indexSearcher = LuceneTestCase.newSearcher(previousReader, false);
       indexSearcher.setSimilarity(s.getSimilarity(true));
-      Weight w = indexSearcher.createNormalizedWeight(q, true);
+      Weight w = indexSearcher.createNormalizedWeight(q, ScoreMode.COMPLETE);
       Scorer scorer = w.scorer((LeafReaderContext)indexSearcher.getTopReaderContext());
       if (scorer != null) {
         DocIdSetIterator iterator = scorer.iterator();
@@ -523,7 +523,7 @@ public class QueryUtils {
 
   /** Check that the scorer and bulk scorer advance consistently. */
   public static void checkBulkScorerSkipTo(Random r, Query query, IndexSearcher searcher) throws IOException {
-    Weight weight = searcher.createNormalizedWeight(query, true);
+    Weight weight = searcher.createNormalizedWeight(query, ScoreMode.COMPLETE);
     for (LeafReaderContext context : searcher.getIndexReader().leaves()) {
       final Scorer scorer = weight.scorer(context);
       final BulkScorer bulkScorer = weight.bulkScorer(context);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java b/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java
index 019c0c4..e88afa7 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java
@@ -62,8 +62,8 @@ public class RandomApproximationQuery extends Query {
   }
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
-    final Weight weight = query.createWeight(searcher, needsScores, boost);
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
+    final Weight weight = query.createWeight(searcher, scoreMode, boost);
     return new RandomApproximationWeight(weight, new Random(random.nextLong()));
   }
 
@@ -109,6 +109,11 @@ public class RandomApproximationQuery extends Query {
     }
 
     @Override
+    public float maxScore() {
+      return scorer.maxScore();
+    }
+
+    @Override
     public int docID() {
       return scorer.docID();
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java b/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
index 918811f..2fdef99 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
@@ -230,7 +230,7 @@ public abstract class ShardSearchingTestBase extends LuceneTestCase {
       @Override
       public Query rewrite(Query original) throws IOException {
         final IndexSearcher localSearcher = new IndexSearcher(getIndexReader());
-        final Weight weight = localSearcher.createNormalizedWeight(original, true);
+        final Weight weight = localSearcher.createNormalizedWeight(original, ScoreMode.COMPLETE);
         final Set<Term> terms = new HashSet<>();
         weight.extractTerms(terms);
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/similarities/AssertingSimilarity.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/similarities/AssertingSimilarity.java b/lucene/test-framework/src/java/org/apache/lucene/search/similarities/AssertingSimilarity.java
index 48028fb..98e49eb 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/similarities/AssertingSimilarity.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/similarities/AssertingSimilarity.java
@@ -91,12 +91,19 @@ public class AssertingSimilarity extends Similarity {
         // result in bounds
         float score = delegateScorer.score(doc, freq);
         assert Float.isFinite(score);
-        // TODO: some tests have negative boosts today
+        assert score <= maxScore(freq);
         assert score >= 0;
         return score;
       }
 
       @Override
+      public float maxScore(float maxFreq) {
+        float maxScore = delegateScorer.maxScore(maxFreq);
+        assert Float.isNaN(maxScore) == false;
+        return maxScore;
+      }
+
+      @Override
       public Explanation explain(int doc, Explanation freq) throws IOException {
         // doc in bounds
         assert doc >= 0;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/similarities/BaseSimilarityTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/similarities/BaseSimilarityTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/search/similarities/BaseSimilarityTestCase.java
index 85a3d6c..5eb64fc 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/similarities/BaseSimilarityTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/similarities/BaseSimilarityTestCase.java
@@ -448,6 +448,8 @@ public abstract class BaseSimilarityTestCase extends LuceneTestCase {
       // check that score isn't infinite or negative
       assertTrue("infinite/NaN score: " + score, Float.isFinite(score));
       assertTrue("negative score: " + score, score >= 0);
+      float maxScore = scorer.maxScore(freq);
+      assertTrue("score > maxScore: " + score + " > " + maxScore, score <= maxScore);
       // check explanation matches
       Explanation explanation = scorer.explain(0, Explanation.match(freq, "freq, occurrences of term within document"));
       if (score != explanation.getValue()) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java b/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java
index 7de01e7..f24a4ff 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java
@@ -19,6 +19,7 @@ package org.apache.lucene.search.spans;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 
 import java.io.IOException;
 import java.util.Objects;
@@ -42,8 +43,8 @@ public class AssertingSpanQuery extends SpanQuery {
   }
 
   @Override
-  public SpanWeight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
-    SpanWeight weight = in.createWeight(searcher, needsScores, boost);
+  public SpanWeight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
+    SpanWeight weight = in.createWeight(searcher, scoreMode, boost);
     return new AssertingSpanWeight(searcher, weight);
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/lucene/test-framework/src/test/org/apache/lucene/search/TestBaseExplanationTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/test/org/apache/lucene/search/TestBaseExplanationTestCase.java b/lucene/test-framework/src/test/org/apache/lucene/search/TestBaseExplanationTestCase.java
index c421647..8e5db28 100644
--- a/lucene/test-framework/src/test/org/apache/lucene/search/TestBaseExplanationTestCase.java
+++ b/lucene/test-framework/src/test/org/apache/lucene/search/TestBaseExplanationTestCase.java
@@ -71,8 +71,9 @@ public class TestBaseExplanationTestCase extends BaseExplanationTestCase {
       this.toggleExplainMatch = toggleExplainMatch;
       this.breakExplainScores = breakExplainScores;
     }
-    public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
-      return new BrokenExplainWeight(this, super.createWeight(searcher,needsScores, boost));
+    @Override
+    public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
+      return new BrokenExplainWeight(this, super.createWeight(searcher,scoreMode, boost));
     }
   }
   

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/contrib/analytics/src/java/org/apache/solr/analytics/facet/AbstractSolrQueryFacet.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/analytics/facet/AbstractSolrQueryFacet.java b/solr/contrib/analytics/src/java/org/apache/solr/analytics/facet/AbstractSolrQueryFacet.java
index d06cfa3..230884a 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/analytics/facet/AbstractSolrQueryFacet.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/analytics/facet/AbstractSolrQueryFacet.java
@@ -21,6 +21,7 @@ import java.util.function.Consumer;
 
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.SimpleCollector;
 import org.apache.solr.analytics.AnalyticsDriver;
 import org.apache.solr.analytics.function.ReductionCollectionManager.ReductionDataCollection;
@@ -74,8 +75,8 @@ public abstract class AbstractSolrQueryFacet extends AnalyticsFacet {
     }
 
     @Override
-    public boolean needsScores() {
-      return false;
+    public ScoreMode scoreMode() {
+      return ScoreMode.COMPLETE_NO_SCORES;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRRescorer.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRRescorer.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRRescorer.java
index 59b764b..2e7049e 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRRescorer.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRRescorer.java
@@ -27,6 +27,7 @@ import org.apache.lucene.search.Explanation;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Rescorer;
 import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.search.Weight;
 import org.apache.solr.search.SolrIndexSearcher;
@@ -114,7 +115,7 @@ public class LTRRescorer extends Rescorer {
     final ScoreDoc[] reranked = new ScoreDoc[topN];
     final List<LeafReaderContext> leaves = searcher.getIndexReader().leaves();
     final LTRScoringQuery.ModelWeight modelWeight = (LTRScoringQuery.ModelWeight) searcher
-        .createNormalizedWeight(scoringQuery, true);
+        .createNormalizedWeight(scoringQuery, ScoreMode.COMPLETE);
 
     scoreFeatures(searcher, firstPassTopDocs,topN, modelWeight, hits, leaves, reranked);
     // Must sort all documents that we reranked, and then select the top
@@ -219,7 +220,7 @@ public class LTRRescorer extends Rescorer {
     final LeafReaderContext context = leafContexts.get(n);
     final int deBasedDoc = docID - context.docBase;
     final Weight modelWeight = searcher.createNormalizedWeight(scoringQuery,
-        true);
+        ScoreMode.COMPLETE);
     return modelWeight.explain(context, deBasedDoc);
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java
index e4acb64..cf564bb 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java
@@ -40,6 +40,7 @@ import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.Explanation;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Weight;
 import org.apache.solr.ltr.feature.Feature;
@@ -187,7 +188,7 @@ public class LTRScoringQuery extends Query {
   }
 
   @Override
-  public ModelWeight createWeight(IndexSearcher searcher, boolean needsScores, float boost)
+  public ModelWeight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost)
       throws IOException {
     final Collection<Feature> modelFeatures = ltrScoringModel.getFeatures();
     final Collection<Feature> allFeatures = ltrScoringModel.getAllFeatures();
@@ -205,10 +206,10 @@ public class LTRScoringQuery extends Query {
     List<Feature.FeatureWeight > featureWeights = new ArrayList<>(features.size());
 
     if (querySemaphore == null) {
-      createWeights(searcher, needsScores, featureWeights, features);
+      createWeights(searcher, scoreMode.needsScores(), featureWeights, features);
     }
     else{
-      createWeightsParallel(searcher, needsScores, featureWeights, features);
+      createWeightsParallel(searcher, scoreMode.needsScores(), featureWeights, features);
     }
     int i=0, j = 0;
     if (this.extractAllFeatures) {
@@ -522,6 +523,11 @@ public class LTRScoringQuery extends Query {
       }
 
       @Override
+      public float maxScore() {
+        return Float.POSITIVE_INFINITY;
+      }
+
+      @Override
       public DocIdSetIterator iterator() {
         return featureTraversalScorer.iterator();
       }
@@ -576,6 +582,11 @@ public class LTRScoringQuery extends Query {
         }
 
         @Override
+        public float maxScore() {
+          return Float.POSITIVE_INFINITY;
+        }
+
+        @Override
         public DocIdSetIterator iterator() {
           return itr;
         }
@@ -658,6 +669,11 @@ public class LTRScoringQuery extends Query {
         }
 
         @Override
+        public float maxScore() {
+          return Float.POSITIVE_INFINITY;
+        }
+        
+        @Override
         public final Collection<ChildScorer> getChildren() {
           final ArrayList<ChildScorer> children = new ArrayList<>();
           for (final Scorer scorer : featureScorers) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/Feature.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/Feature.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/Feature.java
index 082db06..026f760 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/Feature.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/Feature.java
@@ -327,6 +327,10 @@ public abstract class Feature extends Query {
         return constScore;
       }
 
+      @Override
+      public float maxScore() {
+        return constScore;
+      }
     }
 
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/FieldLengthFeature.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/FieldLengthFeature.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/FieldLengthFeature.java
index 00159b9..f8b544f 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/FieldLengthFeature.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/FieldLengthFeature.java
@@ -145,6 +145,11 @@ public class FieldLengthFeature extends Feature {
         final float numTerms = decodeNorm(l);
         return numTerms;
       }
+
+      @Override
+      public float maxScore() {
+        return Float.POSITIVE_INFINITY;
+      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/FieldValueFeature.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/FieldValueFeature.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/FieldValueFeature.java
index 5fcf144..d9e7f02 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/FieldValueFeature.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/FieldValueFeature.java
@@ -140,6 +140,11 @@ public class FieldValueFeature extends Feature {
         }
         return getDefaultValue();
       }
+
+      @Override
+      public float maxScore() {
+        return Float.POSITIVE_INFINITY;
+      }
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/OriginalScoreFeature.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/OriginalScoreFeature.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/OriginalScoreFeature.java
index c960453..d351a04 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/OriginalScoreFeature.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/OriginalScoreFeature.java
@@ -26,6 +26,7 @@ import org.apache.lucene.index.Term;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Weight;
 import org.apache.solr.ltr.DocInfo;
@@ -69,7 +70,7 @@ public class OriginalScoreFeature extends Feature {
     public OriginalScoreWeight(IndexSearcher searcher,
         SolrQueryRequest request, Query originalQuery, Map<String,String[]> efi) throws IOException {
       super(OriginalScoreFeature.this, searcher, request, originalQuery, efi);
-      w = searcher.createNormalizedWeight(originalQuery, true);
+      w = searcher.createNormalizedWeight(originalQuery, ScoreMode.COMPLETE);
     };
 
 
@@ -108,6 +109,11 @@ public class OriginalScoreFeature extends Feature {
       }
 
       @Override
+      public float maxScore() {
+        return Float.POSITIVE_INFINITY;
+      }
+
+      @Override
       public int docID() {
         return originalScorer.docID();
       }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java
index a4ca171..b616bd5 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java
@@ -29,6 +29,7 @@ import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.Bits;
@@ -178,7 +179,7 @@ public class SolrFeature extends Feature {
         // leaving nothing for the phrase query to parse.
         if (query != null) {
           queryAndFilters.add(query);
-          solrQueryWeight = searcher.createNormalizedWeight(query, true);
+          solrQueryWeight = searcher.createNormalizedWeight(query, ScoreMode.COMPLETE);
         } else {
           solrQueryWeight = null;
         }
@@ -285,6 +286,11 @@ public class SolrFeature extends Feature {
                   + name, e);
         }
       }
+
+      @Override
+      public float maxScore() {
+        return Float.POSITIVE_INFINITY;
+      }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/contrib/ltr/src/java/org/apache/solr/ltr/response/transform/LTRFeatureLoggerTransformerFactory.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/response/transform/LTRFeatureLoggerTransformerFactory.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/response/transform/LTRFeatureLoggerTransformerFactory.java
index f625d63..c542d00 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/response/transform/LTRFeatureLoggerTransformerFactory.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/response/transform/LTRFeatureLoggerTransformerFactory.java
@@ -24,6 +24,7 @@ import java.util.Map;
 
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.solr.common.SolrDocument;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.SolrParams;
@@ -242,7 +243,7 @@ public class LTRFeatureLoggerTransformerFactory extends TransformerFactory {
       featureLogger = scoringQuery.getFeatureLogger();
 
       try {
-        modelWeight = scoringQuery.createWeight(searcher, true, 1f);
+        modelWeight = scoringQuery.createWeight(searcher, ScoreMode.COMPLETE, 1f);
       } catch (final IOException e) {
         throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e.getMessage(), e);
       }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestLTRReRankingPipeline.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestLTRReRankingPipeline.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestLTRReRankingPipeline.java
index 081245f..d17dd8d 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestLTRReRankingPipeline.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestLTRReRankingPipeline.java
@@ -36,6 +36,7 @@ import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.Explanation;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.TopDocs;
@@ -276,7 +277,7 @@ public class TestLTRReRankingPipeline extends LuceneTestCase {
     MockModel ltrScoringModel = new MockModel("test",
         features, norms, "test", allFeatures, null);
     LTRScoringQuery query = new LTRScoringQuery(ltrScoringModel);
-    LTRScoringQuery.ModelWeight wgt = query.createWeight(null, true, 1f);
+    LTRScoringQuery.ModelWeight wgt = query.createWeight(null, ScoreMode.COMPLETE, 1f);
     LTRScoringQuery.ModelWeight.ModelScorer modelScr = wgt.scorer(null);
     modelScr.getDocInfo().setOriginalDocScore(new Float(1f));
     for (final Scorer.ChildScorer feat : modelScr.getChildren()) {
@@ -292,7 +293,7 @@ public class TestLTRReRankingPipeline extends LuceneTestCase {
     ltrScoringModel = new MockModel("test", features, norms,
         "test", allFeatures, null);
     query = new LTRScoringQuery(ltrScoringModel);
-    wgt = query.createWeight(null, true, 1f);
+    wgt = query.createWeight(null, ScoreMode.COMPLETE, 1f);
     modelScr = wgt.scorer(null);
     modelScr.getDocInfo().setOriginalDocScore(new Float(1f));
     for (final Scorer.ChildScorer feat : modelScr.getChildren()) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestLTRScoringQuery.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestLTRScoringQuery.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestLTRScoringQuery.java
index e20f7e1..9b9713f 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestLTRScoringQuery.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestLTRScoringQuery.java
@@ -35,6 +35,7 @@ import org.apache.lucene.index.Term;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.TopDocs;
@@ -98,7 +99,7 @@ public class TestLTRScoringQuery extends LuceneTestCase {
     final LeafReaderContext context = leafContexts.get(n);
     final int deBasedDoc = hits.scoreDocs[0].doc - context.docBase;
 
-    final Weight weight = searcher.createNormalizedWeight(model, true);
+    final Weight weight = searcher.createNormalizedWeight(model, ScoreMode.COMPLETE);
     final Scorer scorer = weight.scorer(context);
 
     // rerank using the field final-score

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestSelectiveWeightCreation.java
----------------------------------------------------------------------
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestSelectiveWeightCreation.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestSelectiveWeightCreation.java
index b2cbec9..7193436 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestSelectiveWeightCreation.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/TestSelectiveWeightCreation.java
@@ -33,6 +33,7 @@ import org.apache.lucene.index.Term;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.TopDocs;
@@ -79,7 +80,7 @@ public class TestSelectiveWeightCreation extends TestRerankBase {
     final LeafReaderContext context = leafContexts.get(n);
     final int deBasedDoc = hits.scoreDocs[0].doc - context.docBase;
 
-    final Weight weight = searcher.createNormalizedWeight(model, true);
+    final Weight weight = searcher.createNormalizedWeight(model, ScoreMode.COMPLETE);
     final Scorer scorer = weight.scorer(context);
 
     // rerank using the field final-score

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java b/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
index 1c624e1..574ba72 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
@@ -42,6 +42,7 @@ import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.LeafCollector;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.TermInSetQuery;
@@ -551,8 +552,8 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
     }
 
     @Override
-    public boolean needsScores() {
-      return true; // TODO: is this always true?
+    public ScoreMode scoreMode() {
+      return ScoreMode.COMPLETE; // TODO: is this always true?
     }
 
     public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException {
@@ -638,8 +639,8 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
     }
     
     @Override
-    public boolean needsScores() {
-      return true; // TODO: is this always true?
+    public ScoreMode scoreMode() {
+      return ScoreMode.COMPLETE; // TODO: is this always true?
     }
 
     public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
index f27b386..7dbd311 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
@@ -1481,6 +1481,11 @@ public class QueryComponent extends SearchComponent
     }
 
     @Override
+    public float maxScore() {
+      return Float.POSITIVE_INFINITY;
+    }
+
+    @Override
     public DocIdSetIterator iterator() {
       throw new UnsupportedOperationException();
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java b/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java
index d60d268..8e3ffeb 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java
@@ -42,6 +42,7 @@ import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
@@ -292,7 +293,7 @@ public class RealTimeGetComponent extends SearchComponent
          if (rb.getFilters() != null) {
            for (Query raw : rb.getFilters()) {
              Query q = raw.rewrite(searcherInfo.getSearcher().getIndexReader());
-             Scorer scorer = searcherInfo.getSearcher().createWeight(q, false, 1f).scorer(ctx);
+             Scorer scorer = searcherInfo.getSearcher().createWeight(q, ScoreMode.COMPLETE_NO_SCORES, 1f).scorer(ctx);
              if (scorer == null || segid != scorer.iterator().advance(segid)) {
                // filter doesn't match.
                docid = -1;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/query/FilterQuery.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/query/FilterQuery.java b/solr/core/src/java/org/apache/solr/query/FilterQuery.java
index 785ab5c..7a74798 100644
--- a/solr/core/src/java/org/apache/solr/query/FilterQuery.java
+++ b/solr/core/src/java/org/apache/solr/query/FilterQuery.java
@@ -23,6 +23,7 @@ import org.apache.lucene.search.BoostQuery;
 import org.apache.lucene.search.ConstantScoreQuery;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Weight;
 import org.apache.solr.search.DocSet;
 import org.apache.solr.search.ExtendedQueryBase;
@@ -73,18 +74,18 @@ public class FilterQuery extends ExtendedQueryBase {
   }
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needScores, float boost) throws IOException {
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
     // SolrRequestInfo reqInfo = SolrRequestInfo.getRequestInfo();
 
     if (!(searcher instanceof SolrIndexSearcher)) {
       // delete-by-query won't have SolrIndexSearcher
-      return new BoostQuery(new ConstantScoreQuery(q), 0).createWeight(searcher, needScores, 1f);
+      return new BoostQuery(new ConstantScoreQuery(q), 0).createWeight(searcher, scoreMode, 1f);
     }
 
     SolrIndexSearcher solrSearcher = (SolrIndexSearcher)searcher;
     DocSet docs = solrSearcher.getDocSet(q);
     // reqInfo.addCloseHook(docs);  // needed for off-heap refcounting
 
-    return new BoostQuery(new SolrConstantScoreQuery(docs.getTopFilter()), 0).createWeight(searcher, needScores, 1f);
+    return new BoostQuery(new SolrConstantScoreQuery(docs.getTopFilter()), 0).createWeight(searcher, scoreMode, 1f);
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java b/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java
index 546e9d1..2b0d08a 100644
--- a/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java
+++ b/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java
@@ -38,6 +38,7 @@ import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.Weight;
@@ -139,8 +140,8 @@ public final class SolrRangeQuery extends ExtendedQueryBase implements DocSetPro
   }
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needScores, float boost) throws IOException {
-    return new ConstWeight(searcher, needScores, boost);
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
+    return new ConstWeight(searcher, scoreMode.needsScores(), boost);
     /*
     DocSet docs = createDocSet(searcher.getIndexReader().leaves(), searcher.getIndexReader().maxDoc());
     SolrConstantScoreQuery csq = new SolrConstantScoreQuery( docs.getTopFilter() );
@@ -400,7 +401,7 @@ public final class SolrRangeQuery extends ExtendedQueryBase implements DocSetPro
           bq.add(new TermQuery(new Term( SolrRangeQuery.this.getField(), t.term), termContext), BooleanClause.Occur.SHOULD);
         }
         Query q = new ConstantScoreQuery(bq.build());
-        final Weight weight = searcher.rewrite(q).createWeight(searcher, needScores, score());
+        final Weight weight = searcher.rewrite(q).createWeight(searcher, needScores ? ScoreMode.COMPLETE : ScoreMode.COMPLETE_NO_SCORES, score());
         return segStates[context.ord] = new SegState(weight);
       }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/schema/LatLonType.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/LatLonType.java b/solr/core/src/java/org/apache/solr/schema/LatLonType.java
index 259baa7..31679fb 100644
--- a/solr/core/src/java/org/apache/solr/schema/LatLonType.java
+++ b/solr/core/src/java/org/apache/solr/schema/LatLonType.java
@@ -34,6 +34,7 @@ import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.Explanation;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.Weight;
@@ -484,6 +485,11 @@ class SpatialDistanceQuery extends ExtendedQueryBase implements PostFilter {
       return (float)(dist * qWeight);
     }
 
+    @Override
+    public float maxScore() {
+      return Float.POSITIVE_INFINITY;
+    }
+
     public Explanation explain(Explanation base, int doc) throws IOException {
       if (base.isMatch() == false) {
         return base;
@@ -532,7 +538,7 @@ class SpatialDistanceQuery extends ExtendedQueryBase implements PostFilter {
 
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
     // if we were supposed to use bboxQuery, then we should have been rewritten using that query
     assert bboxQuery == null;
     return new SpatialWeight(searcher, boost);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/AbstractReRankQuery.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/AbstractReRankQuery.java b/solr/core/src/java/org/apache/solr/search/AbstractReRankQuery.java
index cc32761..f7679b0 100644
--- a/solr/core/src/java/org/apache/solr/search/AbstractReRankQuery.java
+++ b/solr/core/src/java/org/apache/solr/search/AbstractReRankQuery.java
@@ -23,6 +23,7 @@ import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Rescorer;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.TopDocsCollector;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.BytesRef;
@@ -76,8 +77,9 @@ public abstract class AbstractReRankQuery extends RankQuery {
 
   protected abstract Query rewrite(Query rewrittenMainQuery) throws IOException;
 
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException{
-    final Weight mainWeight = mainQuery.createWeight(searcher, needsScores, boost);
+  @Override
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException{
+    final Weight mainWeight = mainQuery.createWeight(searcher, scoreMode, boost);
     return new ReRankWeight(mainQuery, reRankQueryRescorer, searcher, mainWeight);
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
index 8c93b52..974df90 100644
--- a/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
@@ -47,6 +47,7 @@ import org.apache.lucene.search.FieldComparator;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.LeafFieldComparator;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.SortField;
@@ -450,6 +451,11 @@ public class CollapsingQParserPlugin extends QParserPlugin {
       return score;
     }
 
+    @Override
+    public float maxScore() {
+      return Float.POSITIVE_INFINITY;
+    }
+
     public int freq() {
       return 0;
     }
@@ -534,7 +540,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
       }
     }
 
-    @Override public boolean needsScores() { return true; }
+    @Override public ScoreMode scoreMode() { return ScoreMode.COMPLETE; }
 
     @Override
     protected void doSetNextReader(LeafReaderContext context) throws IOException {
@@ -769,7 +775,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
 
     }
 
-    @Override public boolean needsScores() { return true; }
+    @Override public ScoreMode scoreMode() { return ScoreMode.COMPLETE; }
 
     @Override
     protected void doSetNextReader(LeafReaderContext context) throws IOException {
@@ -987,7 +993,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
       }
     }
 
-    @Override public boolean needsScores() { return needsScores || super.needsScores(); }
+    @Override public ScoreMode scoreMode() { return needsScores ? ScoreMode.COMPLETE : super.scoreMode(); }
 
     public void setScorer(Scorer scorer) throws IOException {
       this.collapseStrategy.setScorer(scorer);
@@ -1177,7 +1183,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
       }
     }
 
-    @Override public boolean needsScores() { return needsScores || super.needsScores(); }
+    @Override public ScoreMode scoreMode() { return needsScores ? ScoreMode.COMPLETE : super.scoreMode(); }
 
     public void setScorer(Scorer scorer) throws IOException {
       this.collapseStrategy.setScorer(scorer);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/DelegatingCollector.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/DelegatingCollector.java b/solr/core/src/java/org/apache/solr/search/DelegatingCollector.java
index ca66dc3..7dbe3de 100644
--- a/solr/core/src/java/org/apache/solr/search/DelegatingCollector.java
+++ b/solr/core/src/java/org/apache/solr/search/DelegatingCollector.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.search.LeafCollector;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Collector;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.SimpleCollector;
@@ -63,8 +64,8 @@ public class DelegatingCollector extends SimpleCollector {
   }
 
   @Override
-  public boolean needsScores() {
-    return delegate.needsScores();
+  public ScoreMode scoreMode() {
+    return delegate.scoreMode();
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/DocSetCollector.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/DocSetCollector.java b/solr/core/src/java/org/apache/solr/search/DocSetCollector.java
index 3b41c9a..ec1ebc6 100644
--- a/solr/core/src/java/org/apache/solr/search/DocSetCollector.java
+++ b/solr/core/src/java/org/apache/solr/search/DocSetCollector.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 
 import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.SimpleCollector;
 import org.apache.lucene.util.FixedBitSet;
@@ -95,8 +96,8 @@ public class DocSetCollector extends SimpleCollector {
   }
 
   @Override
-  public boolean needsScores() {
-    return false;
+  public ScoreMode scoreMode() {
+    return ScoreMode.COMPLETE_NO_SCORES;
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java
index 6c1714c..6722fee 100644
--- a/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java
@@ -72,7 +72,7 @@ public class ExportQParserPlugin extends QParserPlugin {
     }
 
     public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException{
-      return mainQuery.createWeight(searcher, true, boost);
+      return mainQuery.createWeight(searcher, ScoreMode.COMPLETE, boost);
     }
 
     public Query rewrite(IndexReader reader) throws IOException {
@@ -175,8 +175,8 @@ public class ExportQParserPlugin extends QParserPlugin {
     }
 
     @Override
-    public boolean needsScores() {
-      return true; // TODO: is this the case?
+    public ScoreMode scoreMode() {
+      return ScoreMode.COMPLETE; // TODO: is this the case?
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/Filter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/Filter.java b/solr/core/src/java/org/apache/solr/search/Filter.java
index eb19e1b..3af83e2 100644
--- a/solr/core/src/java/org/apache/solr/search/Filter.java
+++ b/solr/core/src/java/org/apache/solr/search/Filter.java
@@ -27,6 +27,7 @@ import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.Explanation;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.TwoPhaseIterator;
 import org.apache.lucene.search.Weight;
@@ -88,7 +89,7 @@ public abstract class Filter extends Query {
   //
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
     return new Weight(this) {
 
       @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java
index 5309a35..01b0ef8 100644
--- a/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java
@@ -50,6 +50,7 @@ import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchNoDocsQuery;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.ArrayUtil;
@@ -249,7 +250,7 @@ public class GraphTermsQParserPlugin extends QParserPlugin {
     }
 
     @Override
-    public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+    public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
 
       List<TermContext> finalContexts = new ArrayList();
       List<Term> finalTerms = new ArrayList();
@@ -608,7 +609,7 @@ abstract class PointSetQuery extends Query implements DocSetProducer {
 
 
   @Override
-  public final Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+  public final Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
     return new ConstantScoreWeight(this, boost) {
       Filter filter;
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java
index dc75289..7d794c6 100644
--- a/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java
@@ -30,6 +30,7 @@ import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.LeafCollector;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.BitDocIdSet;
@@ -132,7 +133,7 @@ public class HashQParserPlugin extends QParserPlugin {
       }
 
       ConstantScoreQuery constantScoreQuery = new ConstantScoreQuery(new BitsFilter(fixedBitSets));
-      return searcher.rewrite(constantScoreQuery).createWeight(searcher, false, boost);
+      return searcher.rewrite(constantScoreQuery).createWeight(searcher, ScoreMode.COMPLETE_NO_SCORES, boost);
     }
 
     public static class BitsFilter extends Filter {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java
index cc6d6b1..ebf0ebc 100644
--- a/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java
@@ -36,6 +36,7 @@ import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.search.similarities.Similarity;
@@ -165,7 +166,7 @@ class JoinQuery extends Query {
   }
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
     return new JoinQueryWeight((SolrIndexSearcher)searcher, boost);
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/QueryWrapperFilter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/QueryWrapperFilter.java b/solr/core/src/java/org/apache/solr/search/QueryWrapperFilter.java
index fa6e87c..cce8b1a 100644
--- a/solr/core/src/java/org/apache/solr/search/QueryWrapperFilter.java
+++ b/solr/core/src/java/org/apache/solr/search/QueryWrapperFilter.java
@@ -26,6 +26,7 @@ import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.Bits;
@@ -65,7 +66,7 @@ public class QueryWrapperFilter extends Filter {
   public DocIdSet getDocIdSet(final LeafReaderContext context, final Bits acceptDocs) throws IOException {
     // get a private context that is used to rewrite, createWeight and score eventually
     final LeafReaderContext privateContext = context.reader().getContext();
-    final Weight weight = new IndexSearcher(privateContext).createNormalizedWeight(query, false);
+    final Weight weight = new IndexSearcher(privateContext).createNormalizedWeight(query, ScoreMode.COMPLETE_NO_SCORES);
     
     DocIdSet set = new DocIdSet() {
       @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/ReRankCollector.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/ReRankCollector.java b/solr/core/src/java/org/apache/solr/search/ReRankCollector.java
index 1c0deb1..9b6ecb3 100644
--- a/solr/core/src/java/org/apache/solr/search/ReRankCollector.java
+++ b/solr/core/src/java/org/apache/solr/search/ReRankCollector.java
@@ -28,6 +28,7 @@ import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.LeafCollector;
 import org.apache.lucene.search.Rescorer;
 import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.search.TopDocsCollector;
@@ -80,8 +81,8 @@ public class ReRankCollector extends TopDocsCollector {
   }
 
   @Override
-  public boolean needsScores() {
-    return true;
+  public ScoreMode scoreMode() {
+    return ScoreMode.COMPLETE;
   }
 
   public TopDocs topDocs(int start, int howMany) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java b/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java
index 7759602..1f81e1e 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java
@@ -28,6 +28,7 @@ import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Weight;
 
@@ -112,7 +113,7 @@ public class SolrConstantScoreQuery extends Query implements ExtendedQuery {
   }
 
   @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+  public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
     return new SolrConstantScoreQuery.ConstantWeight(searcher, boost);
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a872/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index f577579..9ee5199 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -1059,7 +1059,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
       List<Weight> weights = new ArrayList<>(notCached.size());
       for (Query q : notCached) {
         Query qq = QueryUtils.makeQueryable(q);
-        weights.add(createNormalizedWeight(qq, true));
+        weights.add(createNormalizedWeight(qq, ScoreMode.COMPLETE));
       }
       pf.filter = new FilterImpl(answer, weights);
       pf.hasDeletedDocs = (answer == null);  // if all clauses were uncached, the resulting filter may match deleted docs
@@ -1557,8 +1557,8 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
           }
 
           @Override
-          public boolean needsScores() {
-            return false;
+          public ScoreMode scoreMode() {
+            return ScoreMode.COMPLETE_NO_SCORES;
           }
         };
       } else {
@@ -1578,8 +1578,8 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
           }
 
           @Override
-          public boolean needsScores() {
-            return true;
+          public ScoreMode scoreMode() {
+            return ScoreMode.COMPLETE;
           }
         };
       }
@@ -1667,8 +1667,8 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
           }
 
           @Override
-          public boolean needsScores() {
-            return true;
+          public ScoreMode scoreMode() {
+            return ScoreMode.COMPLETE;
           }
         };