You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mv...@apache.org on 2012/04/06 14:46:55 UTC
svn commit: r1310305 - in /lucene/dev/trunk/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/apache/solr/search...
Author: mvg
Date: Fri Apr 6 12:46:54 2012
New Revision: 1310305
URL: http://svn.apache.org/viewvc?rev=1310305&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/trunk/solr/CHANGES.txt
lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/SearchGroupsFieldCommand.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/TopGroupsFieldCommand.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/EndResultTransformer.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/MainEndResultTransformer.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/SimpleEndResultTransformer.java
lucene/dev/trunk/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java
Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1310305&r1=1310304&r2=1310305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Fri Apr 6 12:46:54 2012
@@ -369,6 +369,9 @@ Bug Fixes
* SOLR-3214: If you use multiple fl entries rather than a comma separated list, all but the first
entry can be ignored if you are using distributed search. (Tomas Fernandez Lobbe via Mark Miller)
+* 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/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java?rev=1310305&r1=1310304&r2=1310305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java Fri Apr 6 12:46:54 2012
@@ -280,6 +280,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()) {
@@ -295,6 +296,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)) {
@@ -306,7 +308,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<BytesRef>> topGroups = new ArrayList<SearchGroup<BytesRef>>(topGroupsParam.length);
@@ -685,7 +687,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/trunk/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java?rev=1310305&r1=1310304&r2=1310305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java Fri Apr 6 12:46:54 2012
@@ -172,6 +172,7 @@ public class ResponseBuilder
public final Map<String, TopGroups<BytesRef>> mergedTopGroups = new HashMap<String, TopGroups<BytesRef>>();
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/trunk/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java?rev=1310305&r1=1310304&r2=1310305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/CommandHandler.java Fri Apr 6 12:46:54 2012
@@ -17,11 +17,7 @@ package org.apache.solr.search.grouping;
* limitations under the License.
*/
-import org.apache.lucene.search.Collector;
-import org.apache.lucene.search.Filter;
-import org.apache.lucene.search.MultiCollector;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TimeLimitingCollector;
+import org.apache.lucene.search.*;
import org.apache.lucene.search.grouping.AbstractAllGroupHeadsCollector;
import org.apache.lucene.search.grouping.term.TermAllGroupHeadsCollector;
import org.apache.lucene.util.OpenBitSet;
@@ -50,6 +46,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;
@@ -84,12 +81,17 @@ public class CommandHandler {
return this;
}
+ public Builder setIncludeHitCount(boolean includeHitCount) {
+ this.includeHitCount = includeHitCount;
+ return this;
+ }
+
public CommandHandler build() {
if (queryCommand == null || searcher == null) {
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);
}
}
@@ -101,19 +103,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")
@@ -130,12 +137,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);
}
}
@@ -185,12 +194,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/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/SearchGroupsFieldCommand.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/SearchGroupsFieldCommand.java?rev=1310305&r1=1310304&r2=1310305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/SearchGroupsFieldCommand.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/SearchGroupsFieldCommand.java Fri Apr 6 12:46:54 2012
@@ -28,6 +28,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;
/**
@@ -70,7 +71,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;
@@ -79,12 +80,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<BytesRef>> result() {
- return collector.getTopGroups(0, true);
+ if (topNGroups > 0) {
+ return firstPassGroupingCollector.getTopGroups(0, true);
+ } else {
+ return Collections.emptyList();
+ }
}
public Sort getSortWithinGroup() {
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/TopGroupsFieldCommand.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/TopGroupsFieldCommand.java?rev=1310305&r1=1310304&r2=1310305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/TopGroupsFieldCommand.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/TopGroupsFieldCommand.java Fri Apr 6 12:46:54 2012
@@ -19,6 +19,7 @@ package org.apache.solr.search.grouping.
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.grouping.GroupDocs;
import org.apache.lucene.search.grouping.SearchGroup;
import org.apache.lucene.search.grouping.term.TermAllGroupsCollector;
import org.apache.lucene.search.grouping.term.TermSecondPassGroupingCollector;
@@ -30,6 +31,7 @@ import org.apache.solr.search.grouping.C
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
/**
@@ -130,6 +132,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 +149,12 @@ public class TopGroupsFieldCommand imple
return collectors;
}
+ @SuppressWarnings("unchecked")
public TopGroups<BytesRef> result() {
+ if (firstPhaseGroups.isEmpty()) {
+ return new TopGroups<BytesRef>(groupSort.getSort(), sortWithinGroup.getSort(), 0, 0, new GroupDocs[0]);
+ }
+
TopGroups<BytesRef> result = secondPassCollector.getTopGroups(0);
if (allGroupsCollector != null) {
result = new TopGroups<BytesRef>(result, allGroupsCollector.getGroupCount());
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java?rev=1310305&r1=1310304&r2=1310305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/distributed/responseprocessor/SearchGroupShardResponseProcessor.java Fri Apr 6 12:46:54 2012
@@ -58,6 +58,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")
@@ -80,7 +81,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<BytesRef>>> topGroups = commandSearchGroups.get(groupField);
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/EndResultTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/EndResultTransformer.java?rev=1310305&r1=1310304&r2=1310305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/EndResultTransformer.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/EndResultTransformer.java Fri Apr 6 12:46:54 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/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java?rev=1310305&r1=1310304&r2=1310305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java Fri Apr 6 12:46:54 2012
@@ -24,11 +24,10 @@ 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.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;
@@ -36,7 +35,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 {
@@ -46,7 +45,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();
@@ -54,7 +56,7 @@ public class GroupedEndResultTransformer
@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);
}
@@ -76,7 +78,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));
}
@@ -94,7 +96,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));
}
@@ -102,7 +104,7 @@ public class GroupedEndResultTransformer
commands.add(entry.getKey(), command);
}
}
- response.add("grouped", commands);
+ rb.rsp.add("grouped", commands);
}
}
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/MainEndResultTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/MainEndResultTransformer.java?rev=1310305&r1=1310304&r2=1310305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/MainEndResultTransformer.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/MainEndResultTransformer.java Fri Apr 6 12:46:54 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/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/SimpleEndResultTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/SimpleEndResultTransformer.java?rev=1310305&r1=1310304&r2=1310305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/SimpleEndResultTransformer.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/SimpleEndResultTransformer.java Fri Apr 6 12:46:54 2012
@@ -24,18 +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 {
- @Override
- 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();
@@ -43,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;
@@ -68,6 +69,6 @@ public class SimpleEndResultTransformer
}
}
- response.add("grouped", commands);
+ rb.rsp.add("grouped", commands);
}
}
Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java?rev=1310305&r1=1310304&r2=1310305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java Fri Apr 6 12:46:54 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:
@@ -142,7 +145,7 @@ public class TestDistributedGrouping ext
query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", "id asc, _docid_ asc");
query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", "{!func}add(" + i1 + ",5) asc, id asc");
query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "facet", "true", "facet.field", t1);
- query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "stats", "true", "stats.field", i1);
+ query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "stats", "true", "stats.field", tlong);
query("q", "kings", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "spellcheck", "true", "spellcheck.build", "true", "qt", "spellCheckCompRH");
query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "facet", "true", "hl","true","hl.fl",t1);
query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "group.sort", "id desc");
@@ -166,6 +169,27 @@ public class TestDistributedGrouping ext
query("q", "*:*", "fq", s1 + ":a", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "group.truncate", "true");
query("q", "*:*", "fq", s1 + ":a", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "group.truncate", "true", "facet", "true", "facet.field", t1);
+ query("q", "*:*", "fq", s1 + ":a", "rows", 0, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "facet", "true", "facet.field", t1);
+ query("q", "*:*", "fq", s1 + ":a", "rows", 0, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " asc, id asc", "group.truncate", "true", "facet", "true", "facet.field", t1);
+
+ ModifiableSolrParams params = new ModifiableSolrParams();
+ Object[] q = {"q", "*:*", "fq", s1 + ":a", "rows", 1, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10};
+
+ for (int i = 0; i < q.length; i += 2) {
+ params.add(q[i].toString(), q[i + 1].toString());
+ }
+
+ setDistributedParams(params);
+
+ 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 * shardsArr.length, 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," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", i1 + " desc", "group.sort", "score desc"); // SOLR-2955
simpleQuery("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 10, "sort", "score desc, _docid_ asc, id asc");