You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2012/04/06 18:21:01 UTC

svn commit: r1310445 - in /lucene/dev/branches/branch_3x/solr: ./ core/src/java/org/apache/solr/handler/component/ core/src/java/org/apache/solr/search/grouping/ core/src/java/org/apache/solr/search/grouping/distributed/command/ core/src/java/org/apach...

Author: rmuir
Date: Fri Apr  6 16:21:00 2012
New Revision: 1310445

URL: http://svn.apache.org/viewvc?rev=1310445&view=rev
Log:
SOLR-3316: Distributed grouping failed when rows parameter was set to 0 and sometimes returned a wrong
 hit count as matches.

Modified:
    lucene/dev/branches/branch_3x/solr/CHANGES.txt
    lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
    lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java
    lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java
    lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/SearchGroupsFieldCommand.java
    lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/TopGroupsFieldCommand.java
    lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java
    lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/EndResultTransformer.java
    lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java
    lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/MainEndResultTransformer.java
    lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/SimpleEndResultTransformer.java
    lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java

Modified: lucene/dev/branches/branch_3x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/CHANGES.txt?rev=1310445&r1=1310444&r2=1310445&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_3x/solr/CHANGES.txt Fri Apr  6 16:21:00 2012
@@ -319,6 +319,9 @@ Bug Fixes
 * SOLR-3200: Fix SignatureUpdateProcessor "all fields" mode to use all 
   fields of each document instead of the fields specified by the first 
   document indexed (Spyros Kapnissis via hossman)
+  
+* SOLR-3316: Distributed grouping failed when rows parameter was set to 0 and 
+  sometimes returned a wrong hit count as matches. (Cody Young, Martijn van Groningen)
 
 Other Changes
 ----------------------

Modified: lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java?rev=1310445&r1=1310444&r2=1310445&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java Fri Apr  6 16:21:00 2012
@@ -24,7 +24,6 @@ import org.apache.lucene.search.*;
 import org.apache.lucene.search.grouping.GroupDocs;
 import org.apache.lucene.search.grouping.SearchGroup;
 import org.apache.lucene.search.grouping.TopGroups;
-import org.apache.lucene.util.BytesRef;
 import org.apache.solr.common.SolrDocument;
 import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.SolrException;
@@ -265,6 +264,7 @@ public class QueryComponent extends Sear
           CommandHandler.Builder topsGroupsActionBuilder = new CommandHandler.Builder()
               .setQueryCommand(cmd)
               .setNeedDocSet(false) // Order matters here
+              .setIncludeHitCount(true)
               .setSearcher(searcher);
 
           for (String field : groupingSpec.getFields()) {
@@ -280,6 +280,7 @@ public class QueryComponent extends Sear
           commandHandler.execute();
           SearchGroupsResultTransformer serializer = new SearchGroupsResultTransformer(searcher);
           rsp.add("firstPhase", commandHandler.processResult(result, serializer));
+          rsp.add("totalHitCount", commandHandler.getTotalHitCount());
           rb.setResult(result);
           return;
         } else if (params.getBool(GroupParams.GROUP_DISTRIBUTED_SECOND, false)) {
@@ -291,7 +292,7 @@ public class QueryComponent extends Sear
           for (String field : groupingSpec.getFields()) {
             String[] topGroupsParam = params.getParams(GroupParams.GROUP_DISTRIBUTED_TOPGROUPS_PREFIX + field);
             if (topGroupsParam == null) {
-              continue;
+              topGroupsParam = new String[0];
             }
 
             List<SearchGroup<String>> topGroups = new ArrayList<SearchGroup<String>>(topGroupsParam.length);
@@ -638,7 +639,7 @@ public class QueryComponent extends Sear
     Map<String, Object> combinedMap = new LinkedHashMap<String, Object>();
     combinedMap.putAll(rb.mergedTopGroups);
     combinedMap.putAll(rb.mergedQueryCommandResults);
-    endResultTransformer.transform(combinedMap, rb.rsp, rb.getGroupingSpec(), solrDocumentSource);
+    endResultTransformer.transform(combinedMap, rb, solrDocumentSource);
   }
 
   private void regularFinishStage(ResponseBuilder rb) {

Modified: lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java?rev=1310445&r1=1310444&r2=1310445&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java Fri Apr  6 16:21:00 2012
@@ -158,6 +158,7 @@ public class ResponseBuilder
   public final Map<String, TopGroups<String>> mergedTopGroups = new HashMap<String, TopGroups<String>>();
   public final Map<String, QueryCommandResult> mergedQueryCommandResults = new HashMap<String, QueryCommandResult>();
   public final Map<Object, SolrDocument> retrievedDocuments = new HashMap<Object, SolrDocument>();
+  public int totalHitCount; // Hit count used when distributed grouping is performed.
   // Used for timeAllowed parameter. First phase elapsed time is subtracted from the time allowed for the second phase.
   public int firstPhaseElapsedTime;
 

Modified: lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java?rev=1310445&r1=1310444&r2=1310445&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java Fri Apr  6 16:21:00 2012
@@ -47,6 +47,7 @@ public class CommandHandler {
     private SolrIndexSearcher searcher;
     private boolean needDocSet = false;
     private boolean truncateGroups = false;
+    private boolean includeHitCount = false;
 
     public Builder setQueryCommand(SolrIndexSearcher.QueryCommand queryCommand) {
       this.queryCommand = queryCommand;
@@ -76,6 +77,11 @@ public class CommandHandler {
       return this;
     }
 
+    public Builder setIncludeHitCount(boolean includeHitCount) {
+      this.includeHitCount = includeHitCount;
+      return this;
+    }
+
     public Builder setTruncateGroups(boolean truncateGroups) {
       this.truncateGroups = truncateGroups;
       return this;
@@ -86,7 +92,7 @@ public class CommandHandler {
         throw new IllegalStateException("All fields must be set");
       }
 
-      return new CommandHandler(queryCommand, commands, searcher, needDocSet, truncateGroups);
+      return new CommandHandler(queryCommand, commands, searcher, needDocSet, truncateGroups, includeHitCount);
     }
 
   }
@@ -98,19 +104,24 @@ public class CommandHandler {
   private final SolrIndexSearcher searcher;
   private final boolean needDocset;
   private final boolean truncateGroups;
+  private final boolean includeHitCount;
   private boolean partialResults = false;
+  private int totalHitCount;
 
   private DocSet docSet;
 
   private CommandHandler(SolrIndexSearcher.QueryCommand queryCommand,
                          List<Command> commands,
                          SolrIndexSearcher searcher,
-                         boolean needDocset, boolean truncateGroups) {
+                         boolean needDocset,
+                         boolean truncateGroups,
+                         boolean includeHitCount) {
     this.queryCommand = queryCommand;
     this.commands = commands;
     this.searcher = searcher;
     this.needDocset = needDocset;
     this.truncateGroups = truncateGroups;
+    this.includeHitCount = includeHitCount;
   }
 
   @SuppressWarnings("unchecked")
@@ -127,12 +138,14 @@ public class CommandHandler {
     Filter luceneFilter = pf.filter;
     Query query = QueryUtils.makeQueryable(queryCommand.getQuery());
 
-    if (truncateGroups && nrOfCommands > 0) {
+    if (truncateGroups) {
       docSet = computeGroupedDocSet(query, luceneFilter, collectors);
     } else if (needDocset) {
       docSet = computeDocSet(query, luceneFilter, collectors);
-    } else {
+    } else if (!collectors.isEmpty()) {
       searchWithTimeLimiter(query, luceneFilter, MultiCollector.wrap(collectors.toArray(new Collector[nrOfCommands])));
+    } else {
+      searchWithTimeLimiter(query, luceneFilter, null);
     }
   }
 
@@ -182,12 +195,25 @@ public class CommandHandler {
     if (queryCommand.getTimeAllowed() > 0 ) {
       collector = new TimeLimitingCollector(collector, TimeLimitingCollector.getGlobalCounter(), queryCommand.getTimeAllowed());
     }
+
+    TotalHitCountCollector hitCountCollector = new TotalHitCountCollector();
+    if (includeHitCount) {
+      collector = MultiCollector.wrap(collector, hitCountCollector);
+    }
+
     try {
       searcher.search(query, luceneFilter, collector);
     } catch (TimeLimitingCollector.TimeExceededException x) {
       partialResults = true;
       logger.warn( "Query: " + query + "; " + x.getMessage() );
     }
+
+    if (includeHitCount) {
+      totalHitCount = hitCountCollector.getTotalHits();
+    }
   }
 
+  public int getTotalHitCount() {
+    return totalHitCount;
+  }
 }

Modified: lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/SearchGroupsFieldCommand.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/SearchGroupsFieldCommand.java?rev=1310445&r1=1310444&r2=1310445&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/SearchGroupsFieldCommand.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/SearchGroupsFieldCommand.java Fri Apr  6 16:21:00 2012
@@ -27,6 +27,7 @@ import org.apache.solr.search.grouping.C
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -69,7 +70,7 @@ public class SearchGroupsFieldCommand im
   private final Sort groupSort;
   private final int topNGroups;
 
-  private TermFirstPassGroupingCollector collector;
+  private TermFirstPassGroupingCollector firstPassGroupingCollector;
 
   private SearchGroupsFieldCommand(SchemaField field, Sort groupSort, int topNGroups) {
     this.field = field;
@@ -78,12 +79,20 @@ public class SearchGroupsFieldCommand im
   }
 
   public List<Collector> create() throws IOException {
-    collector = new TermFirstPassGroupingCollector(field.getName(), groupSort, topNGroups);
-    return Arrays.asList((Collector) collector);
+    if (topNGroups > 0) {
+      firstPassGroupingCollector = new TermFirstPassGroupingCollector(field.getName(), groupSort, topNGroups);
+      return Arrays.asList((Collector) firstPassGroupingCollector);
+    } else {
+      return Collections.emptyList();
+    }
   }
 
   public Collection<SearchGroup<String>> result() {
-    return collector.getTopGroups(0, true);
+    if (topNGroups > 0) {
+      return firstPassGroupingCollector.getTopGroups(0, true);
+    } else {
+      return Collections.emptyList();
+    }
   }
 
   public Sort getSortWithinGroup() {

Modified: lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/TopGroupsFieldCommand.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/TopGroupsFieldCommand.java?rev=1310445&r1=1310444&r2=1310445&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/TopGroupsFieldCommand.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/TopGroupsFieldCommand.java Fri Apr  6 16:21:00 2012
@@ -19,17 +19,14 @@ package org.apache.solr.search.grouping.
 
 import org.apache.lucene.search.Collector;
 import org.apache.lucene.search.Sort;
-import org.apache.lucene.search.grouping.SearchGroup;
-import org.apache.lucene.search.grouping.TermAllGroupsCollector;
-import org.apache.lucene.search.grouping.TermSecondPassGroupingCollector;
-import org.apache.lucene.search.grouping.TopGroups;
-import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.search.grouping.*;
 import org.apache.solr.schema.SchemaField;
 import org.apache.solr.search.grouping.Command;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -130,6 +127,10 @@ public class TopGroupsFieldCommand imple
   }
 
   public List<Collector> create() throws IOException {
+    if (firstPhaseGroups.isEmpty()) {
+      return Collections.emptyList();
+    }
+
     List<Collector> collectors = new ArrayList<Collector>();
     secondPassCollector = new TermSecondPassGroupingCollector(
           field.getName(), firstPhaseGroups, groupSort, sortWithinGroup, maxDocPerGroup, needScores, needMaxScore, true
@@ -143,7 +144,12 @@ public class TopGroupsFieldCommand imple
     return collectors;
   }
 
+  @SuppressWarnings("unchecked")
   public TopGroups<String> result() {
+    if (firstPhaseGroups.isEmpty()) {
+      return new TopGroups<String>(groupSort.getSort(), sortWithinGroup.getSort(), 0, 0, new GroupDocs[0]);
+    }
+
     TopGroups<String> result = secondPassCollector.getTopGroups(0);
     if (allGroupsCollector != null) {
       result = new TopGroups<String>(result, allGroupsCollector.getGroupCount());

Modified: lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java?rev=1310445&r1=1310444&r2=1310445&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java Fri Apr  6 16:21:00 2012
@@ -57,6 +57,7 @@ public class SearchGroupShardResponsePro
     SearchGroupsResultTransformer serializer = new SearchGroupsResultTransformer(rb.req.getSearcher());
     try {
       int maxElapsedTime = 0;
+      int hitCountDuringFirstPhase = 0;
       for (ShardResponse srsp : shardRequest.responses) {
         maxElapsedTime = (int) Math.max(maxElapsedTime, srsp.getSolrResponse().getElapsedTime());
         @SuppressWarnings("unchecked")
@@ -79,7 +80,9 @@ public class SearchGroupShardResponsePro
             shards.add(srsp.getShard());
           }
         }
+        hitCountDuringFirstPhase += (Integer) srsp.getSolrResponse().getResponse().get("totalHitCount");
       }
+      rb.totalHitCount = hitCountDuringFirstPhase;
       rb.firstPhaseElapsedTime = maxElapsedTime;
       for (String groupField : commandSearchGroups.keySet()) {
         List<Collection<SearchGroup<String>>> topGroups = commandSearchGroups.get(groupField);

Modified: lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/EndResultTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/EndResultTransformer.java?rev=1310445&r1=1310444&r2=1310445&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/EndResultTransformer.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/EndResultTransformer.java Fri Apr  6 16:21:00 2012
@@ -19,8 +19,7 @@ package org.apache.solr.search.grouping.
 
 import org.apache.lucene.search.ScoreDoc;
 import org.apache.solr.common.SolrDocument;
-import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.search.grouping.GroupingSpecification;
+import org.apache.solr.handler.component.ResponseBuilder;
 
 import java.util.Map;
 
@@ -35,11 +34,10 @@ public interface EndResultTransformer {
    * Transforms the specified result into its final form and puts it into the specified response.
    *
    * @param result The map containing the grouping result (for grouping by field and query)
-   * @param response The response that will be rendered to the client
-   * @param groupingSpecification The grouping specification
+   * @param rb The response builder containing the response used to render the result and the grouping specification
    * @param solrDocumentSource The source of {@link SolrDocument} instances
    */
-  void transform(Map<String, ?> result, SolrQueryResponse response, GroupingSpecification groupingSpecification, SolrDocumentSource solrDocumentSource);
+  void transform(Map<String, ?> result, ResponseBuilder rb, SolrDocumentSource solrDocumentSource);
 
   /**
    * Abstracts the source for {@link SolrDocument} instances.

Modified: lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java?rev=1310445&r1=1310444&r2=1310445&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java Fri Apr  6 16:21:00 2012
@@ -23,11 +23,10 @@ import org.apache.lucene.search.grouping
 import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.handler.component.ResponseBuilder;
 import org.apache.solr.schema.FieldType;
 import org.apache.solr.schema.SchemaField;
 import org.apache.solr.search.SolrIndexSearcher;
-import org.apache.solr.search.grouping.GroupingSpecification;
 import org.apache.solr.search.grouping.distributed.command.QueryCommandResult;
 
 import java.util.ArrayList;
@@ -35,7 +34,7 @@ import java.util.List;
 import java.util.Map;
 
 /**
- *
+ * Implementation of {@link EndResultTransformer} that keeps each grouped result separate in the final response.
  */
 public class GroupedEndResultTransformer implements EndResultTransformer {
 
@@ -45,7 +44,10 @@ public class GroupedEndResultTransformer
     this.searcher = searcher;
   }
 
-  public void transform(Map<String, ?> result, SolrQueryResponse response, GroupingSpecification groupingSpecification, SolrDocumentSource solrDocumentSource) {
+  /**
+   * {@inheritDoc}
+   */
+  public void transform(Map<String, ?> result, ResponseBuilder rb, SolrDocumentSource solrDocumentSource) {
     NamedList<Object> commands = new NamedList<Object>();
     for (Map.Entry<String, ?> entry : result.entrySet()) {
       Object value = entry.getValue();
@@ -53,7 +55,7 @@ public class GroupedEndResultTransformer
         @SuppressWarnings("unchecked")
         TopGroups<String> topGroups = (TopGroups<String>) value;
         NamedList<Object> command = new SimpleOrderedMap<Object>();
-        command.add("matches", topGroups.totalHitCount);
+        command.add("matches", rb.totalHitCount);
         if (topGroups.totalGroupCount != null) {
           command.add("ngroups", topGroups.totalGroupCount);
         }
@@ -75,7 +77,7 @@ public class GroupedEndResultTransformer
           if (!Float.isNaN(group.maxScore)) {
             docList.setMaxScore(group.maxScore);
           }
-          docList.setStart(groupingSpecification.getGroupOffset());
+          docList.setStart(rb.getGroupingSpec().getGroupOffset());
           for (ScoreDoc scoreDoc : group.scoreDocs) {
             docList.add(solrDocumentSource.retrieve(scoreDoc));
           }
@@ -93,7 +95,7 @@ public class GroupedEndResultTransformer
         if (!Float.isNaN(queryCommandResult.getTopDocs().getMaxScore())) {
           docList.setMaxScore(queryCommandResult.getTopDocs().getMaxScore());
         }
-        docList.setStart(groupingSpecification.getGroupOffset());
+        docList.setStart(rb.getGroupingSpec().getGroupOffset());
         for (ScoreDoc scoreDoc :queryCommandResult.getTopDocs().scoreDocs){
           docList.add(solrDocumentSource.retrieve(scoreDoc));
         }
@@ -101,7 +103,7 @@ public class GroupedEndResultTransformer
         commands.add(entry.getKey(), command);
       }
     }
-    response.add("grouped", commands);
+    rb.rsp.add("grouped", commands);
   }
 
 }

Modified: lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/MainEndResultTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/MainEndResultTransformer.java?rev=1310445&r1=1310444&r2=1310445&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/MainEndResultTransformer.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/MainEndResultTransformer.java Fri Apr  6 16:21:00 2012
@@ -22,24 +22,27 @@ import org.apache.lucene.search.grouping
 import org.apache.lucene.search.grouping.TopGroups;
 import org.apache.lucene.util.BytesRef;
 import org.apache.solr.common.SolrDocumentList;
-import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.search.grouping.GroupingSpecification;
+import org.apache.solr.handler.component.ResponseBuilder;
 
 import java.util.Map;
 
 /**
- *
+ * Implementation of {@link EndResultTransformer} that transforms the grouped result into the main result list in the
+ * response.
  */
 public class MainEndResultTransformer implements EndResultTransformer {
 
-  public void transform(Map<String, ?> result, SolrQueryResponse response, GroupingSpecification groupingSpecification, SolrDocumentSource solrDocumentSource) {
-    Object value = result.get(groupingSpecification.getFields()[0]);
+  /**
+   * {@inheritDoc}
+   */
+  public void transform(Map<String, ?> result, ResponseBuilder rb, SolrDocumentSource solrDocumentSource) {
+    Object value = result.get(rb.getGroupingSpec().getFields()[0]);
     if (TopGroups.class.isInstance(value)) {
       @SuppressWarnings("unchecked")
       TopGroups<BytesRef> topGroups = (TopGroups<BytesRef>) value;
       SolrDocumentList docList = new SolrDocumentList();
-      docList.setStart(groupingSpecification.getOffset());
-      docList.setNumFound(topGroups.totalHitCount);
+      docList.setStart(rb.getGroupingSpec().getOffset());
+      docList.setNumFound(rb.totalHitCount);
 
       Float maxScore = Float.NEGATIVE_INFINITY;
       for (GroupDocs<BytesRef> group : topGroups.groups) {
@@ -53,7 +56,7 @@ public class MainEndResultTransformer im
       if (maxScore != Float.NEGATIVE_INFINITY) {
         docList.setMaxScore(maxScore);
       }
-      response.add("response", docList);
+      rb.rsp.add("response", docList);
     }
   }
 }

Modified: lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/SimpleEndResultTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/SimpleEndResultTransformer.java?rev=1310445&r1=1310444&r2=1310445&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/SimpleEndResultTransformer.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/SimpleEndResultTransformer.java Fri Apr  6 16:21:00 2012
@@ -24,17 +24,19 @@ import org.apache.lucene.util.BytesRef;
 import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.search.grouping.GroupingSpecification;
+import org.apache.solr.handler.component.ResponseBuilder;
 
 import java.util.Map;
 
 /**
- *
+ * Implementation of {@link EndResultTransformer} that transforms the grouped result into a single flat list.
  */
 public class SimpleEndResultTransformer implements EndResultTransformer {
 
-  public void transform(Map<String, ?> result, SolrQueryResponse response, GroupingSpecification groupingSpecification, SolrDocumentSource solrDocumentSource) {
+  /**
+   * {@inheritDoc}
+   */
+  public void transform(Map<String, ?> result, ResponseBuilder rb, SolrDocumentSource solrDocumentSource) {
     NamedList<Object> commands = new SimpleOrderedMap<Object>();
     for (Map.Entry<String, ?> entry : result.entrySet()) {
       Object value = entry.getValue();
@@ -42,12 +44,12 @@ public class SimpleEndResultTransformer 
         @SuppressWarnings("unchecked")
         TopGroups<BytesRef> topGroups = (TopGroups<BytesRef>) value;
         NamedList<Object> command = new SimpleOrderedMap<Object>();
-        command.add("matches", topGroups.totalHitCount);
+        command.add("matches", rb.totalHitCount);
         if (topGroups.totalGroupCount != null) {
           command.add("ngroups", topGroups.totalGroupCount);
         }
         SolrDocumentList docList = new SolrDocumentList();
-        docList.setStart(groupingSpecification.getOffset());
+        docList.setStart(rb.getGroupingSpec().getOffset());
         docList.setNumFound(topGroups.totalHitCount);
 
         Float maxScore = Float.NEGATIVE_INFINITY;
@@ -67,6 +69,6 @@ public class SimpleEndResultTransformer 
       }
     }
 
-    response.add("grouped", commands);
+    rb.rsp.add("grouped", commands);
   }
 }

Modified: lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java?rev=1310445&r1=1310444&r2=1310445&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java (original)
+++ lucene/dev/branches/branch_3x/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java Fri Apr  6 16:21:00 2012
@@ -17,9 +17,12 @@ package org.apache.solr;
  * limitations under the License.
  */
 
+import org.apache.solr.client.solrj.SolrServer;
 import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.util.NamedList;
 
 /**
  * TODO? perhaps use:
@@ -169,6 +172,26 @@ public class TestDistributedGrouping ext
     query("q", "*:*", "fq", s2 + ":a", "rows", 100, "fl", "id," + s1, "group", "true", "group.field", s1, "group.limit", 10, "sort", s1 + " asc, id asc", "group.truncate", "true");
     query("q", "*:*", "fq", s2 + ":a", "rows", 100, "fl", "id," + s1, "group", "true", "group.field", s1, "group.limit", 10, "sort", s1 + " asc, id asc", "group.truncate", "true", "facet", "true", "facet.field", t1);
 
+    query("q", "*:*", "fq", s2 + ":a", "rows", 0, "fl", "id," + s1, "group", "true", "group.field", s1, "group.limit", 10, "sort", s1 + " asc, id asc", "facet", "true", "facet.field", t1);
+    query("q", "*:*", "fq", s2 + ":a", "rows", 0, "fl", "id," + s1, "group", "true", "group.field", s1, "group.limit", 10, "sort", s1 + " asc, id asc", "group.truncate", "true", "facet", "true", "facet.field", t1);
+
+    ModifiableSolrParams params = new ModifiableSolrParams();
+    Object[] q =  {"q", "*:*", "fq", s2 + ":a", "rows", 1, "fl", "id," + s1, "group", "true", "group.field", s1, "group.limit", 10};
+
+    for (int i = 0; i < q.length; i += 2) {
+      params.add(q[i].toString(), q[i + 1].toString());
+    }
+
+    params.set("shards", shards);
+
+    int which = r.nextInt(clients.size());
+    SolrServer client = clients.get(which);
+    QueryResponse rsp = client.query(params);
+    NamedList nl = (NamedList<?>) rsp.getResponse().get("grouped");
+    nl = (NamedList<?>) nl.getVal(0);
+    int matches = (Integer) nl.getVal(0);
+    assertEquals(100 * clients.size(), matches);
+
     // We cannot validate distributed grouping with scoring as first sort. since there is no global idf. We can check if no errors occur
     simpleQuery("q", "*:*", "rows", 100, "fl", "id," + s1, "group", "true", "group.field", s1, "group.limit", 10, "sort", s1 + " desc", "group.sort", "score desc"); // SOLR-2955
     simpleQuery("q", "*:*", "rows", 100, "fl", "id," + s1, "group", "true", "group.field", s1, "group.limit", 10, "sort", "score desc, _docid_ asc, id asc");