lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jpou...@apache.org
Subject [1/2] lucene-solr:master: LUCENE-8405: Remove TopDocs.maxScore.
Date Wed, 18 Jul 2018 07:39:25 GMT
Repository: lucene-solr
Updated Branches:
  refs/heads/master 1ba5cff7b -> 331ccf391


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/grouping/src/java/org/apache/lucene/search/grouping/TopGroupsCollector.java
----------------------------------------------------------------------
diff --git a/lucene/grouping/src/java/org/apache/lucene/search/grouping/TopGroupsCollector.java b/lucene/grouping/src/java/org/apache/lucene/search/grouping/TopGroupsCollector.java
index 7e41a6c..eb75366 100644
--- a/lucene/grouping/src/java/org/apache/lucene/search/grouping/TopGroupsCollector.java
+++ b/lucene/grouping/src/java/org/apache/lucene/search/grouping/TopGroupsCollector.java
@@ -17,15 +17,23 @@
 
 package org.apache.lucene.search.grouping;
 
+import java.io.IOException;
 import java.util.Collection;
 import java.util.Objects;
 import java.util.function.Supplier;
 
+import org.apache.lucene.search.FilterCollector;
+import org.apache.lucene.search.MultiCollector;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.ScoreMode;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.SimpleCollector;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.search.TopDocsCollector;
 import org.apache.lucene.search.TopFieldCollector;
 import org.apache.lucene.search.TopScoreDocCollector;
+import org.apache.lucene.util.ArrayUtil;
 
 /**
  * A second-pass collector that collects the TopDocs for each group, and
@@ -60,17 +68,64 @@ public class TopGroupsCollector<T> extends SecondPassGroupingCollector<T> {
 
   }
 
-  private static class TopDocsReducer<T> extends GroupReducer<T, TopDocsCollector<?>> {
+  private static class MaxScoreCollector extends SimpleCollector {
+    private Scorer scorer;
+    private float maxScore = Float.MIN_VALUE;
+    private boolean collectedAnyHits = false;
 
-    private final Supplier<TopDocsCollector<?>> supplier;
+    public MaxScoreCollector() {}
+
+    public float getMaxScore() {
+      return collectedAnyHits ? maxScore : Float.NaN;
+    }
+
+    @Override
+    public ScoreMode scoreMode() {
+      return ScoreMode.COMPLETE;
+    }
+
+    @Override
+    public void setScorer(Scorer scorer) {
+      this.scorer = scorer;
+    }
+
+    @Override
+    public void collect(int doc) throws IOException {
+      collectedAnyHits = true;
+      maxScore = Math.max(scorer.score(), maxScore);
+    }
+  }
+
+  private static class TopDocsAndMaxScoreCollector extends FilterCollector {
+    private final TopDocsCollector<?> topDocsCollector;
+    private final MaxScoreCollector maxScoreCollector;
+    private final boolean sortedByScore;
+    
+    public TopDocsAndMaxScoreCollector(boolean sortedByScore, TopDocsCollector<?> topDocsCollector, MaxScoreCollector maxScoreCollector) {
+      super(MultiCollector.wrap(topDocsCollector, maxScoreCollector));
+      this.sortedByScore = sortedByScore;
+      this.topDocsCollector = topDocsCollector;
+      this.maxScoreCollector = maxScoreCollector;
+    }
+  }
+
+  private static class TopDocsReducer<T> extends GroupReducer<T, TopDocsAndMaxScoreCollector> {
+
+    private final Supplier<TopDocsAndMaxScoreCollector> supplier;
     private final boolean needsScores;
 
     TopDocsReducer(Sort withinGroupSort,
                    int maxDocsPerGroup, boolean getScores, boolean getMaxScores, boolean fillSortFields) {
       this.needsScores = getScores || getMaxScores || withinGroupSort.needsScores();
-      this.supplier = withinGroupSort == Sort.RELEVANCE ?
-          () -> TopScoreDocCollector.create(maxDocsPerGroup) :
-          () -> TopFieldCollector.create(withinGroupSort, maxDocsPerGroup, fillSortFields, getScores, getMaxScores, true); // TODO: disable exact counts?
+      if (withinGroupSort == Sort.RELEVANCE) {
+        supplier = () -> new TopDocsAndMaxScoreCollector(true, TopScoreDocCollector.create(maxDocsPerGroup), null);
+      } else {
+        supplier = () -> {
+          TopFieldCollector topDocsCollector = TopFieldCollector.create(withinGroupSort, maxDocsPerGroup, fillSortFields, getScores, true); // TODO: disable exact counts?
+          MaxScoreCollector maxScoreCollector = getMaxScores ? new MaxScoreCollector() : null;
+          return new TopDocsAndMaxScoreCollector(false, topDocsCollector, maxScoreCollector);
+        };
+      }
     }
 
     @Override
@@ -79,7 +134,7 @@ public class TopGroupsCollector<T> extends SecondPassGroupingCollector<T> {
     }
 
     @Override
-    protected TopDocsCollector<?> newCollector() {
+    protected TopDocsAndMaxScoreCollector newCollector() {
       return supplier.get();
     }
   }
@@ -95,15 +150,33 @@ public class TopGroupsCollector<T> extends SecondPassGroupingCollector<T> {
     int groupIDX = 0;
     float maxScore = Float.MIN_VALUE;
     for(SearchGroup<T> group : groups) {
-      TopDocsCollector<?> collector = (TopDocsCollector<?>) groupReducer.getCollector(group.groupValue);
-      final TopDocs topDocs = collector.topDocs(withinGroupOffset, maxDocsPerGroup);
+      TopDocsAndMaxScoreCollector collector = (TopDocsAndMaxScoreCollector) groupReducer.getCollector(group.groupValue);
+      final TopDocs topDocs;
+      final float groupMaxScore;
+      if (collector.sortedByScore) {
+        TopDocs allTopDocs = collector.topDocsCollector.topDocs();
+        groupMaxScore = allTopDocs.scoreDocs.length == 0 ? Float.NaN : allTopDocs.scoreDocs[0].score;
+        if (allTopDocs.scoreDocs.length <= withinGroupOffset) {
+          topDocs = new TopDocs(allTopDocs.totalHits, new ScoreDoc[0]);
+        } else {
+          topDocs = new TopDocs(allTopDocs.totalHits, ArrayUtil.copyOfSubArray(allTopDocs.scoreDocs, withinGroupOffset, Math.min(allTopDocs.scoreDocs.length, withinGroupOffset + maxDocsPerGroup)));
+        }
+      } else {
+        topDocs = collector.topDocsCollector.topDocs(withinGroupOffset, maxDocsPerGroup);
+        if (collector.maxScoreCollector == null) {
+          groupMaxScore = Float.NaN;
+        } else {
+          groupMaxScore = collector.maxScoreCollector.getMaxScore();
+        }
+      }
+      
       groupDocsResult[groupIDX++] = new GroupDocs<>(Float.NaN,
-          topDocs.getMaxScore(),
+          groupMaxScore,
           topDocs.totalHits,
           topDocs.scoreDocs,
           group.groupValue,
           group.sortValues);
-      maxScore = Math.max(maxScore, topDocs.getMaxScore());
+      maxScore = Math.max(maxScore, groupMaxScore);
     }
 
     return new TopGroups<>(groupSort.getSort(),

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterStrictPhrases.java
----------------------------------------------------------------------
diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterStrictPhrases.java b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterStrictPhrases.java
index b768382..44a8272 100644
--- a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterStrictPhrases.java
+++ b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterStrictPhrases.java
@@ -540,7 +540,7 @@ public class TestUnifiedHighlighterStrictPhrases extends LuceneTestCase {
     final String indexedText = "x y z x z x a";
     indexWriter.addDocument(newDoc(indexedText));
     initReaderSearcherHighlighter();
-    TopDocs topDocs = new TopDocs(1, new ScoreDoc[]{new ScoreDoc(0, 1f)}, 1f);
+    TopDocs topDocs = new TopDocs(1, new ScoreDoc[]{new ScoreDoc(0, 1f)});
 
     String expected = "<b>x</b> <b>y</b> <b>z</b> x z x <b>a</b>";
     Query q = new SpanNearQuery(new SpanQuery[] {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
----------------------------------------------------------------------
diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
index 0654822..bcdeb87 100644
--- a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
+++ b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
@@ -1013,7 +1013,7 @@ public class TestBlockJoin extends LuceneTestCase {
   private void compareHits(IndexReader r, IndexReader joinR, TopDocs controlHits, Map<Integer, TopDocs> joinResults) throws Exception {
     int currentParentID = -1;
     int childHitSlot = 0;
-    TopDocs childHits = new TopDocs(0, new ScoreDoc[0], 0f);
+    TopDocs childHits = new TopDocs(0, new ScoreDoc[0]);
     for (ScoreDoc controlHit : controlHits.scoreDocs) {
       Document controlDoc = r.document(controlHit.doc);
       int parentID = Integer.parseInt(controlDoc.get("parentID"));

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
----------------------------------------------------------------------
diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
index a0f86af..3f3ac7c 100644
--- a/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
+++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
@@ -1287,7 +1287,6 @@ public class TestJoinUtil extends LuceneTestCase {
         System.out.printf(Locale.ENGLISH, "Expected score: %f | Actual score: %f\n", expectedTopDocs.scoreDocs[i].score, actualTopDocs.scoreDocs[i].score);
       }
     }
-    assertEquals(expectedTopDocs.getMaxScore(), actualTopDocs.getMaxScore(), 0.0f);
 
     for (int i = 0; i < expectedTopDocs.scoreDocs.length; i++) {
       assertEquals(expectedTopDocs.scoreDocs[i].doc, actualTopDocs.scoreDocs[i].doc);
@@ -1647,7 +1646,7 @@ public class TestJoinUtil extends LuceneTestCase {
       Map.Entry<Integer,JoinScore> hit = hits.get(i);
       scoreDocs[i] = new ScoreDoc(hit.getKey(), hit.getValue().score(scoreMode));
     }
-    return new TopDocs(hits.size(), scoreDocs, hits.isEmpty() ? Float.NaN : hits.get(0).getValue().score(scoreMode));
+    return new TopDocs(hits.size(), scoreDocs);
   }
 
   private BitSet createExpectedResult(String queryValue, boolean from, IndexReader topLevelReader, IndexIterationContext context) throws IOException {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/join/src/test/org/apache/lucene/search/join/TestParentChildrenBlockJoinQuery.java
----------------------------------------------------------------------
diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestParentChildrenBlockJoinQuery.java b/lucene/join/src/test/org/apache/lucene/search/join/TestParentChildrenBlockJoinQuery.java
index fe849cb..f6cc6d9 100644
--- a/lucene/join/src/test/org/apache/lucene/search/join/TestParentChildrenBlockJoinQuery.java
+++ b/lucene/join/src/test/org/apache/lucene/search/join/TestParentChildrenBlockJoinQuery.java
@@ -88,7 +88,6 @@ public class TestParentChildrenBlockJoinQuery extends LuceneTestCase {
       TopDocs topDocs = searcher.search(parentChildrenBlockJoinQuery, maxChildDocsPerParent);
       assertEquals(expectedChildDocs, topDocs.totalHits);
       if (expectedChildDocs > 0) {
-        assertEquals(expectedChildDocs, topDocs.getMaxScore(), 0);
         for (int i = 0; i < topDocs.scoreDocs.length; i++) {
           ScoreDoc childScoreDoc = topDocs.scoreDocs[i];
           assertEquals(expectedChildDocs - i, childScoreDoc.score, 0);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/misc/src/java/org/apache/lucene/search/DiversifiedTopDocsCollector.java
----------------------------------------------------------------------
diff --git a/lucene/misc/src/java/org/apache/lucene/search/DiversifiedTopDocsCollector.java b/lucene/misc/src/java/org/apache/lucene/search/DiversifiedTopDocsCollector.java
index dbe4324..bd4978d 100644
--- a/lucene/misc/src/java/org/apache/lucene/search/DiversifiedTopDocsCollector.java
+++ b/lucene/misc/src/java/org/apache/lucene/search/DiversifiedTopDocsCollector.java
@@ -92,21 +92,7 @@ public abstract class DiversifiedTopDocsCollector extends
       return EMPTY_TOPDOCS;
     }
 
-    // We need to compute maxScore in order to set it in TopDocs. If start == 0,
-    // it means the largest element is already in results, use its score as
-    // maxScore. Otherwise pop everything else, until the largest element is
-    // extracted and use its score as maxScore.
-    float maxScore = Float.NaN;
-    if (start == 0) {
-      maxScore = results[0].score;
-    } else {
-      for (int i = globalQueue.size(); i > 1; i--) {
-        globalQueue.pop();
-      }
-      maxScore = globalQueue.pop().score;
-    }
-
-    return new TopDocs(totalHits, results, maxScore);
+    return new TopDocs(totalHits, results);
   }
 
   protected ScoreDocKey insert(ScoreDocKey addition, int docBase,

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/queries/src/test/org/apache/lucene/queries/function/TestIndexReaderFunctions.java
----------------------------------------------------------------------
diff --git a/lucene/queries/src/test/org/apache/lucene/queries/function/TestIndexReaderFunctions.java b/lucene/queries/src/test/org/apache/lucene/queries/function/TestIndexReaderFunctions.java
index ea21074..5223a4b 100644
--- a/lucene/queries/src/test/org/apache/lucene/queries/function/TestIndexReaderFunctions.java
+++ b/lucene/queries/src/test/org/apache/lucene/queries/function/TestIndexReaderFunctions.java
@@ -180,7 +180,7 @@ public class TestIndexReaderFunctions extends LuceneTestCase {
       expected[i] = new ScoreDoc(i, scores[i]);
     }
     TopDocs docs = searcher.search(q, documents.size(),
-        new Sort(new SortField("id", SortField.Type.STRING)), true, false);
+        new Sort(new SortField("id", SortField.Type.STRING)), true);
     CheckHits.checkHits(random(), q, "", searcher, expectedDocs);
     CheckHits.checkHitsQuery(q, expected, docs.scoreDocs, expectedDocs);
     CheckHits.checkExplanations(q, "", searcher);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java
----------------------------------------------------------------------
diff --git a/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java b/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java
index b12f026..1d7fefb 100644
--- a/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java
+++ b/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java
@@ -648,7 +648,7 @@ public class TestValueSources extends LuceneTestCase {
       expected[i] = new ScoreDoc(i, scores[i]);
     }
     TopDocs docs = searcher.search(q, documents.size(),
-        new Sort(new SortField("id", SortField.Type.STRING)), true, false);
+        new Sort(new SortField("id", SortField.Type.STRING)), true);
     CheckHits.checkHits(random(), q, "", searcher, expectedDocs);
     CheckHits.checkHitsQuery(q, expected, docs.scoreDocs, expectedDocs);
     CheckHits.checkExplanations(q, "", searcher);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/queries/src/test/org/apache/lucene/queries/payloads/TestPayloadTermQuery.java
----------------------------------------------------------------------
diff --git a/lucene/queries/src/test/org/apache/lucene/queries/payloads/TestPayloadTermQuery.java b/lucene/queries/src/test/org/apache/lucene/queries/payloads/TestPayloadTermQuery.java
index 9621e1e..f22793c 100644
--- a/lucene/queries/src/test/org/apache/lucene/queries/payloads/TestPayloadTermQuery.java
+++ b/lucene/queries/src/test/org/apache/lucene/queries/payloads/TestPayloadTermQuery.java
@@ -158,7 +158,6 @@ public class TestPayloadTermQuery extends LuceneTestCase {
     //they should all have the exact same score, because they all contain seventy once, and we set
     //all the other similarity factors to be 1
 
-    assertTrue(hits.getMaxScore() + " does not equal: " + 1, hits.getMaxScore() == 1);
     for (int i = 0; i < hits.scoreDocs.length; i++) {
       ScoreDoc doc = hits.scoreDocs[i];
       assertTrue(doc.score + " does not equal: " + 1, doc.score == 1);
@@ -200,7 +199,6 @@ public class TestPayloadTermQuery extends LuceneTestCase {
     //all the other similarity factors to be 1
 
     //System.out.println("Hash: " + seventyHash + " Twice Hash: " + 2*seventyHash);
-    assertTrue(hits.getMaxScore() + " does not equal: " + 4.0, hits.getMaxScore() == 4.0);
     //there should be exactly 10 items that score a 4, all the rest should score a 2
     //The 10 items are: 70 + i*100 where i in [0-9]
     int numTens = 0;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/sandbox/src/java/org/apache/lucene/document/FloatPointNearestNeighbor.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/FloatPointNearestNeighbor.java b/lucene/sandbox/src/java/org/apache/lucene/document/FloatPointNearestNeighbor.java
index 90a80b6..80a5e7d 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/FloatPointNearestNeighbor.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/FloatPointNearestNeighbor.java
@@ -378,6 +378,6 @@ public class FloatPointNearestNeighbor {
       NearestHit hit = hits[i];
       scoreDocs[i] = new FieldDoc(hit.docID, 0.0f, new Object[] { (float)Math.sqrt(hit.distanceSquared) });
     }
-    return new TopFieldDocs(totalHits, scoreDocs, null, 0.0f);
+    return new TopFieldDocs(totalHits, scoreDocs, null);
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
index 1e5e4bd..7b45c6b 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
@@ -330,6 +330,6 @@ public class LatLonPoint extends Field {
       NearestNeighbor.NearestHit hit = hits[i];
       scoreDocs[i] = new FieldDoc(hit.docID, 0.0f, new Object[] {Double.valueOf(hit.distanceMeters)});
     }
-    return new TopFieldDocs(totalHits, scoreDocs, null, 0.0f);
+    return new TopFieldDocs(totalHits, scoreDocs, null);
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java
----------------------------------------------------------------------
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java
index 85bb6d1..ad76224 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java
@@ -647,7 +647,7 @@ public class AnalyzingInfixSuggester extends Lookup implements Closeable {
     //System.out.println("finalQuery=" + finalQuery);
 
     // Sort by weight, descending:
-    TopFieldCollector c = TopFieldCollector.create(SORT, num, true, false, false, false);
+    TopFieldCollector c = TopFieldCollector.create(SORT, num, true, false, false);
     List<LookupResult> results = null;
     SearcherManager mgr;
     IndexSearcher searcher;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/TopSuggestDocs.java
----------------------------------------------------------------------
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/TopSuggestDocs.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/TopSuggestDocs.java
index 1ffcbdc..ec76ce0 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/TopSuggestDocs.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/TopSuggestDocs.java
@@ -31,7 +31,7 @@ public class TopSuggestDocs extends TopDocs {
   /**
    * Singleton for empty {@link TopSuggestDocs}
    */
-  public final static TopSuggestDocs EMPTY = new TopSuggestDocs(0, new SuggestScoreDoc[0], 0);
+  public final static TopSuggestDocs EMPTY = new TopSuggestDocs(0, new SuggestScoreDoc[0]);
 
   /**
    * {@link org.apache.lucene.search.ScoreDoc} with an
@@ -92,8 +92,8 @@ public class TopSuggestDocs extends TopDocs {
    * {@link TopSuggestDocs.SuggestScoreDoc}
    * instead of {@link org.apache.lucene.search.ScoreDoc}
    */
-  public TopSuggestDocs(int totalHits, SuggestScoreDoc[] scoreDocs, float maxScore) {
-    super(totalHits, scoreDocs, maxScore);
+  public TopSuggestDocs(int totalHits, SuggestScoreDoc[] scoreDocs) {
+    super(totalHits, scoreDocs);
   }
 
   /**
@@ -124,7 +124,7 @@ public class TopSuggestDocs extends TopDocs {
     }
     SuggestScoreDoc[] topNResults = priorityQueue.getResults();
     if (topNResults.length > 0) {
-      return new TopSuggestDocs(topNResults.length, topNResults, topNResults[0].score);
+      return new TopSuggestDocs(topNResults.length, topNResults);
     } else {
       return TopSuggestDocs.EMPTY;
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/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 90db227..1eae018 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
@@ -177,7 +177,7 @@ public class TopSuggestDocsCollector extends SimpleCollector {
     }
 
     if (suggestScoreDocs.length > 0) {
-      return new TopSuggestDocs(suggestScoreDocs.length, suggestScoreDocs, suggestScoreDocs[0].score);
+      return new TopSuggestDocs(suggestScoreDocs.length, suggestScoreDocs);
     } else {
       return TopSuggestDocs.EMPTY;
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java b/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
index d8960a1..537731e 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
@@ -1042,7 +1042,6 @@ public final class TestUtil {
 
   public static void assertEquals(TopDocs expected, TopDocs actual) {
     Assert.assertEquals("wrong total hits", expected.totalHits, actual.totalHits);
-    Assert.assertEquals("wrong maxScore", expected.getMaxScore(), actual.getMaxScore(), 0.0);
     Assert.assertEquals("wrong hit count", expected.scoreDocs.length, actual.scoreDocs.length);
     for(int hitIDX=0;hitIDX<expected.scoreDocs.length;hitIDX++) {
       final ScoreDoc expectedSD = expected.scoreDocs[hitIDX];

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/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 2662490..8b8159e 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
@@ -135,7 +135,7 @@ public class LTRRescorer extends Rescorer {
       }
     });
 
-    return new TopDocs(firstPassTopDocs.totalHits, reranked, reranked[0].score);
+    return new TopDocs(firstPassTopDocs.totalHits, reranked);
   }
 
   public void scoreFeatures(IndexSearcher indexSearcher, TopDocs firstPassTopDocs,

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/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 e0708b9..89067e9 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
@@ -245,7 +245,7 @@ public class TestLTRReRankingPipeline extends LuceneTestCase {
 
       final ScoreDoc[] slice = new ScoreDoc[topN];
       System.arraycopy(hits.scoreDocs, 0, slice, 0, topN);
-      hits = new TopDocs(hits.totalHits, slice, hits.getMaxScore());
+      hits = new TopDocs(hits.totalHits, slice);
       hits = rescorer.rescore(searcher, hits, topN);
       for (int i = topN - 1, j = 0; i >= 0; i--, j++) {
         log.info("doc {} in pos {}", searcher.doc(hits.scoreDocs[j].doc)

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/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 9ffea4b..e7b5433 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
@@ -437,7 +437,7 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
           docs[i] = scoreDoc.doc;
           scores[i] = scoreDoc.score;
         }
-        DocSlice slice = new DocSlice(0, docs.length, docs, scores, topDocs.totalHits, topDocs.getMaxScore());
+        DocSlice slice = new DocSlice(0, docs.length, docs, scores, topDocs.totalHits, Float.NaN);
 
         if(fieldType instanceof StrField) {
           final BytesRef bytesRef = ordBytes.get((int)groupValue);
@@ -535,7 +535,7 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
       DocIdSetIterator iterator = new BitSetIterator(groupBits, 0); // cost is not useful here
       int group;
       while ((group = iterator.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
-        Collector collector = (sort == null) ? TopScoreDocCollector.create(limit) : TopFieldCollector.create(sort, limit, false, false, false, true);
+        Collector collector = (sort == null) ? TopScoreDocCollector.create(limit) : TopFieldCollector.create(sort, limit, false, false, true);
         groups.put(group, collector);
       }
 
@@ -619,7 +619,7 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
       Iterator<LongCursor> iterator = groupSet.iterator();
       while (iterator.hasNext()) {
         LongCursor cursor = iterator.next();
-        Collector collector = (sort == null) ? TopScoreDocCollector.create(limit) : TopFieldCollector.create(sort, limit, false, false, false, true);
+        Collector collector = (sort == null) ? TopScoreDocCollector.create(limit) : TopFieldCollector.create(sort, limit, false, false, true);
         groups.put(cursor.value, collector);
       }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/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 dbaf3db..64464d4 100644
--- a/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java
@@ -180,7 +180,7 @@ public class ExportQParserPlugin extends QParserPlugin {
 
       ScoreDoc[] scoreDocs = getScoreDocs(howMany);
       assert scoreDocs.length <= totalHits;
-      return new TopDocs(totalHits, scoreDocs, 0.0f);
+      return new TopDocs(totalHits, scoreDocs);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/solr/core/src/java/org/apache/solr/search/Grouping.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/Grouping.java b/solr/core/src/java/org/apache/solr/search/Grouping.java
index 4500464..fff536d 100644
--- a/solr/core/src/java/org/apache/solr/search/Grouping.java
+++ b/solr/core/src/java/org/apache/solr/search/Grouping.java
@@ -834,6 +834,7 @@ public class Grouping {
 
     public Query query;
     TopDocsCollector topCollector;
+    MaxScoreCollector maxScoreCollector;
     FilterCollector collector;
 
     @Override
@@ -844,25 +845,37 @@ public class Grouping {
     @Override
     protected Collector createFirstPassCollector() throws IOException {
       DocSet groupFilt = searcher.getDocSet(query);
-      topCollector = newCollector(withinGroupSort, needScores);
-      collector = new FilterCollector(groupFilt, topCollector);
-      return collector;
-    }
-
-    TopDocsCollector newCollector(Sort sort, boolean needScores) throws IOException {
       int groupDocsToCollect = getMax(groupOffset, docsPerGroup, maxDoc);
-      if (sort == null || sort.equals(Sort.RELEVANCE)) {
-        return TopScoreDocCollector.create(groupDocsToCollect);
+      Collector subCollector;
+      if (withinGroupSort == null || withinGroupSort.equals(Sort.RELEVANCE)) {
+        subCollector = topCollector = TopScoreDocCollector.create(groupDocsToCollect);
       } else {
-        return TopFieldCollector.create(searcher.weightSort(sort), groupDocsToCollect, false, needScores, needScores, true);
+        topCollector = TopFieldCollector.create(searcher.weightSort(withinGroupSort), groupDocsToCollect, false, needScores, true);
+        if (needScores) {
+          maxScoreCollector = new MaxScoreCollector();
+          subCollector = MultiCollector.wrap(topCollector, maxScoreCollector);
+        } else {
+          subCollector = topCollector;
+        }
       }
+      collector = new FilterCollector(groupFilt, subCollector);
+      return collector;
     }
 
     @Override
     protected void finish() throws IOException {
       TopDocsCollector topDocsCollector = (TopDocsCollector) collector.getDelegate();
       TopDocs topDocs = topDocsCollector.topDocs();
-      GroupDocs<String> groupDocs = new GroupDocs<>(Float.NaN, topDocs.getMaxScore(), topDocs.totalHits, topDocs.scoreDocs, query.toString(), null);
+      float maxScore;
+      if (withinGroupSort == null || withinGroupSort.equals(Sort.RELEVANCE)) {
+        maxScore = topDocs.scoreDocs.length == 0 ? Float.NaN : topDocs.scoreDocs[0].score;
+      } else if (needScores) {
+        maxScore = maxScoreCollector.getMaxScore();
+      } else {
+        maxScore = Float.NaN;
+      }
+      
+      GroupDocs<String> groupDocs = new GroupDocs<>(Float.NaN, maxScore, topDocs.totalHits, topDocs.scoreDocs, query.toString(), null);
       if (main) {
         mainResult = getDocList(groupDocs);
       } else {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/solr/core/src/java/org/apache/solr/search/MaxScoreCollector.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/MaxScoreCollector.java b/solr/core/src/java/org/apache/solr/search/MaxScoreCollector.java
new file mode 100644
index 0000000..f972450
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/search/MaxScoreCollector.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.search;
+
+import java.io.IOException;
+
+import org.apache.lucene.search.Collector;
+import org.apache.lucene.search.ScoreMode;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.SimpleCollector;
+
+/** A {@link Collector} for the maximum score value. */
+public class MaxScoreCollector extends SimpleCollector {
+  private Scorer scorer;
+  private float maxScore = Float.MIN_VALUE;
+  private boolean collectedAnyHits = false;
+
+  public MaxScoreCollector() {}
+
+  public float getMaxScore() {
+    return collectedAnyHits ? maxScore : Float.NaN;
+  }
+
+  @Override
+  public ScoreMode scoreMode() {
+    // Should be TOP_SCORES but this would wrap the scorer unnecessarily since
+    // this collector is only used in a MultiCollector.
+    return ScoreMode.COMPLETE;
+  }
+
+  @Override
+  public void setScorer(Scorer scorer) {
+    this.scorer = scorer;
+  }
+
+  @Override
+  public void collect(int doc) throws IOException {
+    collectedAnyHits = true;
+    maxScore = Math.max(scorer.score(), maxScore);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/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 a1689dd..a94a412 100644
--- a/solr/core/src/java/org/apache/solr/search/ReRankCollector.java
+++ b/solr/core/src/java/org/apache/solr/search/ReRankCollector.java
@@ -67,7 +67,7 @@ public class ReRankCollector extends TopDocsCollector {
     } else {
       sort = sort.rewrite(searcher);
       //scores are needed for Rescorer (regardless of whether sort needs it)
-      this.mainCollector = TopFieldCollector.create(sort, Math.max(this.reRankDocs, length), false, true, true, true);
+      this.mainCollector = TopFieldCollector.create(sort, Math.max(this.reRankDocs, length), false, true, true);
     }
     this.searcher = searcher;
     this.reRankQueryRescorer = reRankQueryRescorer;
@@ -118,7 +118,8 @@ public class ReRankCollector extends TopDocsCollector {
 
         IntIntHashMap boostedDocs = QueryElevationComponent.getBoostDocs((SolrIndexSearcher)searcher, boostedPriority, requestContext);
 
-        Arrays.sort(rescoredDocs.scoreDocs, new BoostedComp(boostedDocs, mainDocs.scoreDocs, rescoredDocs.getMaxScore()));
+        float maxScore = rescoredDocs.scoreDocs.length == 0 ? Float.NaN : rescoredDocs.scoreDocs[0].score;
+        Arrays.sort(rescoredDocs.scoreDocs, new BoostedComp(boostedDocs, mainDocs.scoreDocs, maxScore));
       }
 
       if(howMany == rescoredDocs.scoreDocs.length) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/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 44e12a7..122de2b 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -1540,7 +1540,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
       // ... see comments in populateNextCursorMarkFromTopDocs for cache issues (SOLR-5595)
       final boolean fillFields = (null != cursor);
       final FieldDoc searchAfter = (null != cursor ? cursor.getSearchAfterFieldDoc() : null);
-      return TopFieldCollector.create(weightedSort, len, searchAfter, fillFields, needScores, needScores, true);
+      return TopFieldCollector.create(weightedSort, len, searchAfter, fillFields, needScores, true);
     }
   }
 
@@ -1617,14 +1617,19 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
       qr.setNextCursorMark(cmd.getCursorMark());
     } else {
       final TopDocsCollector topCollector = buildTopDocsCollector(len, cmd);
+      MaxScoreCollector maxScoreCollector = null;
       Collector collector = topCollector;
+      if ((cmd.getFlags() & GET_SCORES) != 0) {
+        maxScoreCollector = new MaxScoreCollector();
+        collector = MultiCollector.wrap(topCollector, maxScoreCollector);
+      }
       buildAndRunCollectorChain(qr, query, collector, cmd, pf.postFilter);
 
       totalHits = topCollector.getTotalHits();
       TopDocs topDocs = topCollector.topDocs(0, len);
       populateNextCursorMarkFromTopDocs(qr, cmd, topDocs);
 
-      maxScore = totalHits > 0 ? topDocs.getMaxScore() : 0.0f;
+      maxScore = totalHits > 0 ? (maxScoreCollector == null ? Float.NaN : maxScoreCollector.getMaxScore()) : 0.0f;
       nDocsReturned = topDocs.scoreDocs.length;
       ids = new int[nDocsReturned];
       scores = (cmd.getFlags() & GET_SCORES) != 0 ? new float[nDocsReturned] : null;
@@ -1712,7 +1717,15 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
 
       final TopDocsCollector topCollector = buildTopDocsCollector(len, cmd);
       DocSetCollector setCollector = new DocSetCollector(maxDoc);
-      Collector collector = MultiCollector.wrap(topCollector, setCollector);
+      MaxScoreCollector maxScoreCollector = null;
+      List<Collector> collectors = new ArrayList<>(Arrays.asList(topCollector, setCollector));
+
+      if ((cmd.getFlags() & GET_SCORES) != 0) {
+        maxScoreCollector = new MaxScoreCollector();
+        collectors.add(maxScoreCollector);
+      }
+
+      Collector collector = MultiCollector.wrap(collectors);
 
       buildAndRunCollectorChain(qr, query, collector, cmd, pf.postFilter);
 
@@ -1723,7 +1736,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
 
       TopDocs topDocs = topCollector.topDocs(0, len);
       populateNextCursorMarkFromTopDocs(qr, cmd, topDocs);
-      maxScore = totalHits > 0 ? topDocs.getMaxScore() : 0.0f;
+      maxScore = totalHits > 0 ? (maxScoreCollector == null ? Float.NaN : maxScoreCollector.getMaxScore()) : 0.0f;
       nDocsReturned = topDocs.scoreDocs.length;
 
       ids = new int[nDocsReturned];

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommand.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommand.java b/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommand.java
index e8b61bc..321936b 100644
--- a/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommand.java
+++ b/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommand.java
@@ -19,6 +19,7 @@ package org.apache.solr.search.grouping.distributed.command;
 import org.apache.lucene.search.*;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.search.DocSet;
+import org.apache.solr.search.MaxScoreCollector;
 import org.apache.solr.search.QParser;
 import org.apache.solr.search.SolrIndexSearcher;
 import org.apache.solr.search.SyntaxError;
@@ -110,8 +111,9 @@ public class QueryCommand implements Command<QueryCommandResult> {
   private final boolean needScores;
   private final String queryString;
 
-  private TopDocsCollector collector;
+  private TopDocsCollector topDocsCollector;
   private FilterCollector filterCollector;
+  private MaxScoreCollector maxScoreCollector;
 
   private QueryCommand(Sort sort, Query query, int docsToCollect, boolean needScores, DocSet docSet, String queryString) {
     this.sort = sort;
@@ -124,18 +126,32 @@ public class QueryCommand implements Command<QueryCommandResult> {
 
   @Override
   public List<Collector> create() throws IOException {
+    Collector subCollector;
     if (sort == null || sort.equals(Sort.RELEVANCE)) {
-      collector = TopScoreDocCollector.create(docsToCollect);
+      subCollector = topDocsCollector = TopScoreDocCollector.create(docsToCollect);
     } else {
-      collector = TopFieldCollector.create(sort, docsToCollect, true, needScores, needScores, true);
+      topDocsCollector = TopFieldCollector.create(sort, docsToCollect, true, needScores, true);
+      if (needScores) {
+        maxScoreCollector = new MaxScoreCollector();
+        subCollector = MultiCollector.wrap(topDocsCollector, maxScoreCollector);
+      } else {
+        subCollector = topDocsCollector;
+      }
     }
-    filterCollector = new FilterCollector(docSet, collector);
+    filterCollector = new FilterCollector(docSet, subCollector);
     return Arrays.asList((Collector) filterCollector);
   }
 
   @Override
   public QueryCommandResult result() {
-    return new QueryCommandResult(collector.topDocs(), filterCollector.getMatches());
+    TopDocs topDocs = topDocsCollector.topDocs();
+    float maxScore;
+    if (sort == null) {
+      maxScore = topDocs.scoreDocs.length == 0 ? Float.NaN : topDocs.scoreDocs[0].score;
+    } else {
+      maxScore = maxScoreCollector == null ? Float.NaN : maxScoreCollector.getMaxScore();
+    }
+    return new QueryCommandResult(topDocs, filterCollector.getMatches(), maxScore);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommandResult.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommandResult.java b/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommandResult.java
index 8114a46..391ecfa 100644
--- a/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommandResult.java
+++ b/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommandResult.java
@@ -25,10 +25,12 @@ public class QueryCommandResult {
 
   private final TopDocs topDocs;
   private final int matches;
+  private final float maxScore;
 
-  public QueryCommandResult(TopDocs topDocs, int matches) {
+  public QueryCommandResult(TopDocs topDocs, int matches, float maxScore) {
     this.topDocs = topDocs;
     this.matches = matches;
+    this.maxScore = maxScore;
   }
 
   public TopDocs getTopDocs() {
@@ -38,4 +40,8 @@ public class QueryCommandResult {
   public int getMatches() {
     return matches;
   }
+
+  public float getMaxScore() {
+    return maxScore;
+  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/TopGroupsShardResponseProcessor.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/TopGroupsShardResponseProcessor.java b/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/TopGroupsShardResponseProcessor.java
index d05be0d..e2dd299 100644
--- a/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/TopGroupsShardResponseProcessor.java
+++ b/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/TopGroupsShardResponseProcessor.java
@@ -137,7 +137,7 @@ public class TopGroupsShardResponseProcessor implements ShardResponseProcessor {
         QueryCommandResult queryCommandResult = (QueryCommandResult) result.get(query);
         if (individualShardInfo != null) { // keep track of this when shards.info=true
           numFound += queryCommandResult.getMatches();
-          float thisMax = queryCommandResult.getTopDocs().getMaxScore();
+          float thisMax = queryCommandResult.getMaxScore();
           if (Float.isNaN(maxScore) || thisMax > maxScore) maxScore = thisMax;
         }
         commandTopDocs.get(query).add(queryCommandResult);
@@ -168,9 +168,17 @@ public class TopGroupsShardResponseProcessor implements ShardResponseProcessor {
       List<QueryCommandResult> queryCommandResults = commandTopDocs.get(query);
       List<TopDocs> topDocs = new ArrayList<>(queryCommandResults.size());
       int mergedMatches = 0;
+      float maxScore = Float.NaN;
       for (QueryCommandResult queryCommandResult : queryCommandResults) {
-        topDocs.add(queryCommandResult.getTopDocs());
+        TopDocs thisTopDocs = queryCommandResult.getTopDocs();
+        topDocs.add(thisTopDocs);
         mergedMatches += queryCommandResult.getMatches();
+        if (thisTopDocs.scoreDocs.length > 0) {
+          float thisMaxScore = queryCommandResult.getMaxScore();
+          if (Float.isNaN(maxScore) || thisMaxScore > maxScore) {
+            maxScore = thisMaxScore;
+          }
+        }
       }
 
       int topN = rb.getGroupingSpec().getOffset() + rb.getGroupingSpec().getLimit();
@@ -180,7 +188,7 @@ public class TopGroupsShardResponseProcessor implements ShardResponseProcessor {
       } else {
         mergedTopDocs = TopDocs.merge(withinGroupSort, topN, topDocs.toArray(new TopFieldDocs[topDocs.size()]));
       }
-      rb.mergedQueryCommandResults.put(query, new QueryCommandResult(mergedTopDocs, mergedMatches));
+      rb.mergedQueryCommandResults.put(query, new QueryCommandResult(mergedTopDocs, mergedMatches, maxScore));
     }
 
     Map<Object, ShardDoc> resultIds = new HashMap<>();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java b/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java
index 8d2b3dc..a5ce1ff 100644
--- a/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java
+++ b/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java
@@ -108,11 +108,11 @@ public class TopGroupsResultTransformer implements ShardResultTransformer<List<C
         ScoreDoc[] scoreDocs = transformToNativeShardDoc(documents, groupSort, shard, schema);
         final TopDocs topDocs;
         if (withinGroupSort.equals(Sort.RELEVANCE)) {
-          topDocs = new TopDocs(totalHits.longValue(), scoreDocs, maxScore);
+          topDocs = new TopDocs(totalHits.longValue(), scoreDocs);
         } else {
-          topDocs = new TopFieldDocs(totalHits.longValue(), scoreDocs, withinGroupSort.getSort(), maxScore);
+          topDocs = new TopFieldDocs(totalHits.longValue(), scoreDocs, withinGroupSort.getSort());
         }
-        result.put(key, new QueryCommandResult(topDocs, matches));
+        result.put(key, new QueryCommandResult(topDocs, matches, maxScore));
         continue;
       }
 
@@ -242,8 +242,8 @@ public class TopGroupsResultTransformer implements ShardResultTransformer<List<C
     queryResult.add("matches", result.getMatches());
     queryResult.add("totalHits", result.getTopDocs().totalHits);
     // debug: assert !Float.isNaN(result.getTopDocs().getMaxScore()) == rb.getGroupingSpec().isNeedScore();
-    if (!Float.isNaN(result.getTopDocs().getMaxScore())) {
-      queryResult.add("maxScore", result.getTopDocs().getMaxScore());
+    if (!Float.isNaN(result.getMaxScore())) {
+      queryResult.add("maxScore", result.getMaxScore());
     }
     List<NamedList> documents = new ArrayList<>();
     queryResult.add("documents", documents);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java b/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java
index b060590..6c9372c 100644
--- a/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java
+++ b/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java
@@ -91,8 +91,8 @@ public class GroupedEndResultTransformer implements EndResultTransformer {
         command.add("matches", queryCommandResult.getMatches());
         SolrDocumentList docList = new SolrDocumentList();
         docList.setNumFound(queryCommandResult.getTopDocs().totalHits);
-        if (!Float.isNaN(queryCommandResult.getTopDocs().getMaxScore())) {
-          docList.setMaxScore(queryCommandResult.getTopDocs().getMaxScore());
+        if (!Float.isNaN(queryCommandResult.getMaxScore())) {
+          docList.setMaxScore(queryCommandResult.getMaxScore());
         }
         docList.setStart(rb.getGroupingSpec().getWithinGroupOffset());
         for (ScoreDoc scoreDoc :queryCommandResult.getTopDocs().scoreDocs){

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/solr/core/src/test/org/apache/solr/search/TestRankQueryPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/TestRankQueryPlugin.java b/solr/core/src/test/org/apache/solr/search/TestRankQueryPlugin.java
index 6d2143a..f72fd56 100644
--- a/solr/core/src/test/org/apache/solr/search/TestRankQueryPlugin.java
+++ b/solr/core/src/test/org/apache/solr/search/TestRankQueryPlugin.java
@@ -723,7 +723,7 @@ public class TestRankQueryPlugin extends QParserPlugin {
         }
       });
       ScoreDoc[] scoreDocs = list.toArray(new ScoreDoc[list.size()]);
-      return new TopDocs(list.size(), scoreDocs, 0.0f);
+      return new TopDocs(list.size(), scoreDocs);
     }
 
     public TopDocs topDocs(int start, int len) {
@@ -785,7 +785,7 @@ public class TestRankQueryPlugin extends QParserPlugin {
         }
       });
       ScoreDoc[] scoreDocs = list.toArray(new ScoreDoc[list.size()]);
-      return new TopDocs(list.size(), scoreDocs, 0.0f);
+      return new TopDocs(list.size(), scoreDocs);
     }
 
     public TopDocs topDocs(int start, int len) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/solr/core/src/test/org/apache/solr/search/TestSort.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/TestSort.java b/solr/core/src/test/org/apache/solr/search/TestSort.java
index 03365b4..abfbe8a 100644
--- a/solr/core/src/test/org/apache/solr/search/TestSort.java
+++ b/solr/core/src/test/org/apache/solr/search/TestSort.java
@@ -283,9 +283,8 @@ public class TestSort extends SolrTestCaseJ4 {
         final String nullRep2 = luceneSort2 || sortMissingFirst2 && !reverse2 || sortMissingLast2 && reverse2 ? "" : "zzz";
 
         boolean trackScores = r.nextBoolean();
-        boolean trackMaxScores = r.nextBoolean();
         boolean scoreInOrder = r.nextBoolean();
-        final TopFieldCollector topCollector = TopFieldCollector.create(sort, top, true, trackScores, trackMaxScores, true);
+        final TopFieldCollector topCollector = TopFieldCollector.create(sort, top, true, trackScores, true);
 
         final List<MyDoc> collectedDocs = new ArrayList<>();
         // delegate and collect docs ourselves

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSort.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSort.java b/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSort.java
index 2c0862f..ddf4cc3 100644
--- a/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSort.java
+++ b/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSort.java
@@ -1664,12 +1664,6 @@ public class TestFieldCacheSort extends LuceneTestCase {
                     Collections.singletonMap("id", Type.LEGACY_INTEGER));
     w.close();
     Query q = new TermQuery(new Term("body", "text"));
-    IndexSearcher s = newSearcher(r);
-    float maxScore = s.search(q , 10).getMaxScore();
-    assertEquals(maxScore, s.search(q, 3, Sort.INDEXORDER, random().nextBoolean(), true).getMaxScore(), 0.0);
-    assertEquals(maxScore, s.search(q, 3, Sort.RELEVANCE, random().nextBoolean(), true).getMaxScore(), 0.0);
-    assertEquals(maxScore, s.search(q, 3, new Sort(new SortField[] {new SortField("id", SortField.Type.INT, false)}), random().nextBoolean(), true).getMaxScore(), 0.0);
-    assertEquals(maxScore, s.search(q, 3, new Sort(new SortField[] {new SortField("id", SortField.Type.INT, true)}), random().nextBoolean(), true).getMaxScore(), 0.0);
     TestUtil.checkReader(r);
     r.close();
     d.close();
@@ -1681,27 +1675,27 @@ public class TestFieldCacheSort extends LuceneTestCase {
     Query query = new TermQuery(new Term("contents", "foo"));
   
     Sort sort = new Sort();
-    TopDocs td = empty.search(query, 10, sort, true, true);
+    TopDocs td = empty.search(query, 10, sort, true);
     assertEquals(0, td.totalHits);
 
     sort.setSort(SortField.FIELD_DOC);
-    td = empty.search(query, 10, sort, true, true);
+    td = empty.search(query, 10, sort, true);
     assertEquals(0, td.totalHits);
 
     sort.setSort(new SortField("int", SortField.Type.INT), SortField.FIELD_DOC);
-    td = empty.search(query, 10, sort, true, true);
+    td = empty.search(query, 10, sort, true);
     assertEquals(0, td.totalHits);
     
     sort.setSort(new SortField("string", SortField.Type.STRING, true), SortField.FIELD_DOC);
-    td = empty.search(query, 10, sort, true, true);
+    td = empty.search(query, 10, sort, true);
     assertEquals(0, td.totalHits);
     
     sort.setSort(new SortField("string_val", SortField.Type.STRING_VAL, true), SortField.FIELD_DOC);
-    td = empty.search(query, 10, sort, true, true);
+    td = empty.search(query, 10, sort, true);
     assertEquals(0, td.totalHits);
 
     sort.setSort(new SortField("float", SortField.Type.FLOAT), new SortField("string", SortField.Type.STRING));
-    td = empty.search(query, 10, sort, true, true);
+    td = empty.search(query, 10, sort, true);
     assertEquals(0, td.totalHits);
   }
   
@@ -1743,7 +1737,7 @@ public class TestFieldCacheSort extends LuceneTestCase {
 
     TopDocs expected = searcher.search(new TermQuery(new Term("value", "foo")), 10);
     assertEquals(1, expected.totalHits);
-    TopDocs actual = searcher.search(new TermQuery(new Term("value", "foo")), 10, sort, true, true);
+    TopDocs actual = searcher.search(new TermQuery(new Term("value", "foo")), 10, sort, true);
     
     assertEquals(expected.totalHits, actual.totalHits);
     assertEquals(expected.scoreDocs[0].score, actual.scoreDocs[0].score, 0F);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/331ccf39/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java b/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java
index 58069cd..f9653e0 100644
--- a/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java
+++ b/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java
@@ -168,9 +168,9 @@ public class TestFieldCacheSortRandom extends LuceneTestCase {
       int queryType = random.nextInt(2);
       if (queryType == 0) {
         hits = s.search(new ConstantScoreQuery(f),
-                        hitCount, sort, random.nextBoolean(), random.nextBoolean());
+                        hitCount, sort, random.nextBoolean());
       } else {
-        hits = s.search(f, hitCount, sort, random.nextBoolean(), random.nextBoolean());
+        hits = s.search(f, hitCount, sort, random.nextBoolean());
       }
 
       if (VERBOSE) {


Mime
View raw message