You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by yo...@apache.org on 2010/11/02 22:09:10 UTC

svn commit: r1030220 - in /lucene/dev/trunk/solr/src: java/org/apache/solr/handler/component/QueryComponent.java java/org/apache/solr/search/Grouping.java java/org/apache/solr/search/SolrIndexSearcher.java test/org/apache/solr/TestGroupingSearch.java

Author: yonik
Date: Tue Nov  2 21:09:10 2010
New Revision: 1030220

URL: http://svn.apache.org/viewvc?rev=1030220&view=rev
Log:
SOLR-236: refactor field collapsing, pull out of SolrIndexSearcher

Modified:
    lucene/dev/trunk/solr/src/java/org/apache/solr/handler/component/QueryComponent.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/Grouping.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java
    lucene/dev/trunk/solr/src/test/org/apache/solr/TestGroupingSearch.java

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/handler/component/QueryComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/handler/component/QueryComponent.java?rev=1030220&r1=1030219&r2=1030220&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/handler/component/QueryComponent.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/handler/component/QueryComponent.java Tue Nov  2 21:09:10 2010
@@ -300,8 +300,8 @@ public class QueryComponent extends Sear
     boolean doGroup = params.getBool(GroupParams.GROUP, false);
     if (doGroup) {
       try {
-        cmd.groupCommands = new ArrayList<Grouping.Command>();
-        
+        Grouping grouping = new Grouping(searcher, result, cmd);
+
         String[] fields = params.getParams(GroupParams.GROUP_FIELD);
         String[] funcs = params.getParams(GroupParams.GROUP_FUNC);
         String[] queries = params.getParams(GroupParams.GROUP_QUERY);
@@ -330,7 +330,7 @@ public class QueryComponent extends Sear
           for (String groupByStr : funcs) {
             QParser parser = QParser.getParser(groupByStr, "func", rb.req);
             Query q = parser.getQuery();
-            Grouping.CommandFunc gc = new Grouping.CommandFunc();
+            Grouping.CommandFunc gc = grouping.new CommandFunc();
             gc.groupSort = groupSort;
 
             if (q instanceof FunctionQuery) {
@@ -343,8 +343,9 @@ public class QueryComponent extends Sear
             gc.docsPerGroup = docsPerGroupDefault;
             gc.groupOffset = groupOffsetDefault;
             gc.offset = cmd.getOffset();
+            gc.sort = cmd.getSort();
 
-            cmd.groupCommands.add(gc);
+            grouping.add(gc);
           }
         }
 
@@ -352,7 +353,7 @@ public class QueryComponent extends Sear
           for (String groupByStr : queries) {
             QParser parser = QParser.getParser(groupByStr, null, rb.req);
             Query gq = parser.getQuery();
-            Grouping.CommandQuery gc = new Grouping.CommandQuery();
+            Grouping.CommandQuery gc = grouping.new CommandQuery();
             gc.query = gq;
             gc.groupSort = groupSort;
             gc.key = groupByStr;
@@ -360,26 +361,23 @@ public class QueryComponent extends Sear
             gc.docsPerGroup = docsPerGroupDefault;
             gc.groupOffset = groupOffsetDefault;
 
-            cmd.groupCommands.add(gc);
+            grouping.add(gc);
           }
         }
 
 
-        if (cmd.groupCommands.size() == 0)
-          cmd.groupCommands = null;
+        if (rb.doHighlights || rb.isDebug()) {
+          // we need a single list of the returned docs
+          cmd.setFlags(SolrIndexSearcher.GET_DOCLIST);
+        }
 
-        if (cmd.groupCommands != null) {
-          if (rb.doHighlights || rb.isDebug()) {
-            // we need a single list of the returned docs
-            cmd.setFlags(SolrIndexSearcher.GET_DOCLIST);
-          }
+        // searcher.search(result,cmd);
+        grouping.execute();
+        rb.setResult( result );
+        rsp.add("grouped", result.groupedResults);
+        // TODO: get "hits" a different way to log
+        return;
 
-          searcher.search(result,cmd);
-          rb.setResult( result );
-          rsp.add("grouped", result.groupedResults);
-          // TODO: get "hits" a different way to log
-          return;
-        }
       } catch (ParseException e) {
         throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);
       }

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/Grouping.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/Grouping.java?rev=1030220&r1=1030219&r2=1030220&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/Grouping.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/Grouping.java Tue Nov  2 21:09:10 2010
@@ -19,6 +19,8 @@ package org.apache.solr.search;
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.search.*;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.search.function.DocValues;
 import org.apache.solr.search.function.ValueSource;
 
@@ -27,27 +29,286 @@ import java.util.*;
 
 public class Grouping {
 
-  public static class Command {
-    public String key;  // the name to use for this group in the response
-    public Sort groupSort;  // the sort of the documents *within* a single group.
+
+  public abstract class Command {
+    public String key;       // the name to use for this group in the response
+    public Sort groupSort;   // the sort of the documents *within* a single group.
+    public Sort sort;        // the sort between groups
     public int docsPerGroup; // how many docs in each group - from "group.limit" param, default=1
-    public int groupOffset; // the offset within each group (for paging within each group)
-    public int numGroups;   // how many groups - defaults to the "rows" parameter
-    public int offset;   // offset into the list of groups
+    public int groupOffset;  // the offset within each group (for paging within each group)
+    public int numGroups;    // how many groups - defaults to the "rows" parameter
+    public int offset;       // offset into the list of groups
+
+
+    abstract void prepare() throws IOException;
+    abstract Collector createCollector() throws IOException;
+    Collector createNextCollector() throws IOException {
+      return null;
+    }
+    abstract void finish() throws IOException;
+
+    abstract int getMatches();
+
+    NamedList commonResponse() {
+      NamedList groupResult = new SimpleOrderedMap();
+      grouped.add(key, groupResult);  // grouped={ key={
+
+      int this_matches = getMatches();
+      groupResult.add("matches", this_matches);
+      maxMatches = Math.max(maxMatches, this_matches);
+      return groupResult;
+    }
+
+    DocList getDocList(TopDocsCollector collector) {
+      int docsToCollect = getMax(groupOffset, docsPerGroup, maxDoc);
+
+      // TODO: implement a DocList impl that doesn't need to start at offset=0
+      TopDocs topDocs = collector.topDocs(0, docsToCollect);
+
+      int ids[] = new int[topDocs.scoreDocs.length];
+      float[] scores = needScores ? new float[topDocs.scoreDocs.length] : null;
+      for (int i=0; i<ids.length; i++) {
+        ids[i] = topDocs.scoreDocs[i].doc;
+        if (scores != null)
+          scores[i] = topDocs.scoreDocs[i].score;
+      }
+
+      float score = topDocs.getMaxScore();
+      maxScore = Math.max(maxScore, score);
+      DocSlice docs = new DocSlice(groupOffset, Math.max(0, ids.length - groupOffset), ids, scores, topDocs.totalHits, score);
+
+      if (getDocList) {
+        DocIterator iter = docs.iterator();
+        while (iter.hasNext())
+          idSet.add(iter.nextDoc());
+      }
+      return docs;
+    }
+
+    void addDocList(NamedList rsp, TopDocsCollector collector) {
+      rsp.add("doclist", getDocList(collector));
+    }
   }
 
-  public static class CommandQuery extends Command {
+  public class CommandQuery extends Command {
     public Query query;
+
+    TopDocsCollector topCollector;
+    FilterCollector collector;
+
+    @Override
+    void prepare() throws IOException {
+    }
+
+    @Override
+    Collector createCollector() throws IOException {
+      int docsToCollect = getMax(groupOffset, docsPerGroup, maxDoc);
+      DocSet groupFilt = searcher.getDocSet(query);
+      topCollector = newCollector(groupSort, docsToCollect, false, needScores);
+      collector = new FilterCollector(groupFilt, topCollector);
+      return collector;
+    }
+
+    @Override
+    void finish() throws IOException {
+      NamedList rsp = commonResponse();
+      addDocList(rsp, (TopDocsCollector)collector.getCollector());
+    }
+
+    @Override
+    int getMatches() {
+      return collector.getMatches();
+    }
   }
 
-  public static class CommandFunc extends Command {
+  
+  public class CommandFunc extends Command {
     public ValueSource groupBy;
 
 
-    // todo - find a better place to store these
-    transient Map context;
-    transient Collector collector;
+    int maxGroupToFind;
+    Map context;
+    TopGroupCollector collector = null;
+    Phase2GroupCollector collector2;
+    
+    @Override
+    void prepare() throws IOException {
+        Map context = ValueSource.newContext();
+        groupBy.createWeight(context, searcher);
+    }
+
+    @Override
+    Collector createCollector() throws IOException {
+      maxGroupToFind = getMax(offset, numGroups, maxDoc);
+
+      if (compareSorts(sort, groupSort)) {
+        collector = new TopGroupSortCollector(groupBy, context, normalizeSort(sort), normalizeSort(groupSort), maxGroupToFind);
+      } else {
+        collector = new TopGroupCollector(groupBy, context, normalizeSort(sort), maxGroupToFind);
+      }
+      return collector;
+    }
+
+    @Override
+    Collector createNextCollector() throws IOException {
+      int docsToCollect = getMax(groupOffset, docsPerGroup, maxDoc);
+      if (docsToCollect < 0 || docsToCollect > maxDoc) docsToCollect = maxDoc;
+
+      collector2 = new Phase2GroupCollector(collector, groupBy, context, groupSort, docsToCollect, needScores, offset);
+      return collector2;
+    }
+
+    @Override
+    void finish() throws IOException {
+      NamedList groupResult = commonResponse();
+
+      if (collector.orderedGroups == null) collector.buildSet();
+
+      List groupList = new ArrayList();
+      groupResult.add("groups", groupList);        // grouped={ key={ groups=[
+
+      int skipCount = offset;
+      for (SearchGroup group : collector.orderedGroups) {
+        if (skipCount > 0) {
+          skipCount--;
+          continue;
+        }
+        NamedList nl = new SimpleOrderedMap();
+        groupList.add(nl);                         // grouped={ key={ groups=[ {
+
+        nl.add("groupValue", group.groupValue.toObject());
+
+        SearchGroupDocs groupDocs = collector2.groupMap.get(group.groupValue);
+        addDocList(nl, groupDocs.collector);
+      }
+    }
+
+    @Override
+    int getMatches() {
+      return collector.getMatches();
+    }
+  }
+
+
+
+  static Sort byScoreDesc = new Sort();
+
+  static boolean compareSorts(Sort sort1, Sort sort2) {
+    return sort1 == sort2 || normalizeSort(sort1).equals(normalizeSort(sort2)); 
+  }
+
+  /** returns a sort by score desc if null */
+  static Sort normalizeSort(Sort sort) {
+    return sort==null ? byScoreDesc : sort;
+  } 
+
+  static int getMax(int offset, int len, int max) {
+    int v = len<0 ? max : offset + len;
+    if (v < 0 || v > max) v = max;
+    return v;
   }
+
+  static TopDocsCollector newCollector(Sort sort, int numHits, boolean fillFields, boolean needScores) throws IOException {
+    if (sort==null || sort==byScoreDesc) {
+      return TopScoreDocCollector.create(numHits, true);
+    } else {
+      return TopFieldCollector.create(sort, numHits, false, needScores, needScores, true);
+    }
+  }
+
+
+  final SolrIndexSearcher searcher;
+  final SolrIndexSearcher.QueryResult qr;
+  final SolrIndexSearcher.QueryCommand cmd;
+  final List<Command> commands = new ArrayList<Command>();
+
+  public Grouping(SolrIndexSearcher searcher, SolrIndexSearcher.QueryResult qr, SolrIndexSearcher.QueryCommand cmd) {
+    this.searcher = searcher;
+    this.qr = qr;
+    this.cmd = cmd;
+  }
+
+  public void add(Grouping.Command groupingCommand) {
+    commands.add(groupingCommand);
+  }
+
+  int maxDoc;
+  boolean needScores;
+  boolean getDocSet;
+  boolean getDocList; // doclist needed for debugging or highlighting
+  Query query;
+  DocSet filter;
+  Filter luceneFilter;
+  NamedList grouped = new SimpleOrderedMap();
+  Set<Integer> idSet = new LinkedHashSet<Integer>();  // used for tracking unique docs when we need a doclist
+  int maxMatches;  // max number of matches from any grouping command  
+  float maxScore = Float.NEGATIVE_INFINITY;  // max score seen in any doclist
+  
+  public void execute() throws IOException {
+    DocListAndSet out = new DocListAndSet();
+    qr.setDocListAndSet(out);
+
+    filter = cmd.getFilter()!=null ? cmd.getFilter() : searcher.getDocSet(cmd.getFilterList());
+
+    maxDoc = searcher.maxDoc();
+
+    needScores = (cmd.getFlags() & SolrIndexSearcher.GET_SCORES) != 0;
+    getDocSet = (cmd.getFlags() & SolrIndexSearcher.GET_DOCSET) != 0;
+    getDocList = (cmd.getFlags() & SolrIndexSearcher.GET_DOCLIST) != 0; // doclist needed for debugging or highlighting
+    query = QueryUtils.makeQueryable(cmd.getQuery());
+
+    for (Command cmd : commands) {
+      cmd.prepare();
+    }
+    
+    List<Collector> collectors = new ArrayList<Collector>(commands.size());
+    for (Command cmd : commands) {
+      Collector collector = cmd.createCollector();
+      if (collector != null)
+        collectors.add(collector);
+    }
+
+    Collector allCollectors = MultiCollector.wrap(collectors.toArray(new Collector[collectors.size()]));
+    DocSetCollector setCollector = null;
+    if (getDocSet) {
+      setCollector = new DocSetDelegateCollector(maxDoc>>6, maxDoc, allCollectors);
+      allCollectors = setCollector;
+    }
+
+    searcher.search(query, luceneFilter, allCollectors);
+
+    if (getDocSet) {
+      qr.setDocSet(setCollector.getDocSet());
+    }
+
+    collectors.clear();
+    for (Command cmd : commands) {
+      Collector collector = cmd.createNextCollector();
+      if (collector != null)
+        collectors.add(collector);
+    }
+
+    if (collectors.size() > 0) {
+      searcher.search(query, luceneFilter, MultiCollector.wrap(collectors.toArray(new Collector[collectors.size()])));
+    }
+
+    for (Command cmd : commands) {
+      cmd.finish();
+    }
+
+    qr.groupedResults = grouped;
+
+    if (getDocList) {
+      int sz = idSet.size();
+      int[] ids = new int[sz];
+      int idx = 0;
+      for (int val : idSet) {
+        ids[idx++] = val;
+      }
+      qr.setDocList(new DocSlice(0, sz, ids, null, maxMatches, maxScore));
+    }
+  }
+
 }
 
 
@@ -82,11 +343,11 @@ abstract class GroupCollector extends Co
 
 class FilterCollector extends GroupCollector {
   private final DocSet filter;
-  private final TopFieldCollector collector;
+  private final Collector collector;
   private int docBase;
   private int matches;
 
-  public FilterCollector(DocSet filter, TopFieldCollector collector) throws IOException {
+  public FilterCollector(DocSet filter, Collector collector) throws IOException {
     this.filter = filter;
     this.collector = collector;
   }
@@ -119,7 +380,7 @@ class FilterCollector extends GroupColle
     return matches;
   }
 
-  TopFieldCollector getTopFieldCollector() {
+  Collector getCollector() {
     return collector;
   }
 }
@@ -527,7 +788,10 @@ class Phase2GroupCollector extends Colle
       }
       SearchGroupDocs groupDocs = new SearchGroupDocs();
       groupDocs.groupValue = group.groupValue;
-      groupDocs.collector = TopFieldCollector.create(sort, docsPerGroup, getSortFields, getScores, getScores, true);
+      if (sort==null)
+        groupDocs.collector = TopScoreDocCollector.create(docsPerGroup, true);        
+      else
+        groupDocs.collector = TopFieldCollector.create(sort, docsPerGroup, getSortFields, getScores, getScores, true);
       groupMap.put(groupDocs.groupValue, groupDocs);
     }
 
@@ -571,6 +835,6 @@ class Phase2GroupCollector extends Colle
 // disad: blows up the size of SearchGroup if we need many of them, and couples implementations
 class SearchGroupDocs {
   public MutableValue groupValue;
-  TopFieldCollector collector;
+  TopDocsCollector collector;
 }
 

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java?rev=1030220&r1=1030219&r2=1030220&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java Tue Nov  2 21:09:10 2010
@@ -983,238 +983,19 @@ public class SolrIndexSearcher extends I
     return qr.getDocList();
   }
 
-  private static final int NO_CHECK_QCACHE       = 0x80000000;
-  private static final int GET_DOCSET            = 0x40000000;
-  private static final int NO_CHECK_FILTERCACHE  = 0x20000000;
+  static final int NO_CHECK_QCACHE       = 0x80000000;
+  static final int GET_DOCSET            = 0x40000000;
+  static final int NO_CHECK_FILTERCACHE  = 0x20000000;
   
   public static final int GET_DOCLIST           =        0x02; // get the documents actually returned in a response
   public static final int GET_SCORES             =       0x01;
 
 
-  private void groupBy(QueryResult qr, QueryCommand cmd) throws IOException {
-    DocListAndSet out = new DocListAndSet();
-    qr.setDocListAndSet(out);
-
-    DocSet filter = cmd.getFilter()!=null ? cmd.getFilter() : getDocSet(cmd.getFilterList());
-
-    int maxDoc = maxDoc();
-
-    boolean needScores = (cmd.getFlags() & GET_SCORES) != 0;
-    boolean getDocSet = (cmd.getFlags() & GET_DOCSET) != 0;
-    boolean getDocList = (cmd.getFlags() & GET_DOCLIST) != 0; // doclist needed for debugging or highlighting
-    Query query = QueryUtils.makeQueryable(cmd.getQuery());
-
-    final Filter luceneFilter = filter==null ? null : filter.getTopFilter();
-
-    Sort sort = cmd.getSort();
-    if (sort == null) sort = new Sort();
-
-    List<GroupCollector> collectors = new ArrayList<GroupCollector>(cmd.groupCommands.size());
-    for (Grouping.Command groupCommand : cmd.groupCommands) {
-      // TODO: perhaps use some methods rather than instanceof
-      if (groupCommand instanceof Grouping.CommandFunc) {
-        Grouping.CommandFunc gc = (Grouping.CommandFunc)groupCommand;
-        Map context = ValueSource.newContext();
-        gc.groupBy.createWeight(context, this);
-        TopGroupCollector collector;
-
-        int groupsToCollect = gc.numGroups<0 ? maxDoc : gc.offset + gc.numGroups;
-        if (groupsToCollect < 0 || groupsToCollect > maxDoc) groupsToCollect = maxDoc;
-
-        if (gc.groupSort != null && gc.groupSort != sort) {
-          collector = new TopGroupSortCollector(gc.groupBy, context, sort, gc.groupSort, groupsToCollect);
-        } else {
-          collector = new TopGroupCollector(gc.groupBy, context, sort, groupsToCollect);
-        }
-        collectors.add(collector);
-
-        // for next phase
-        gc.context = context;
-        gc.collector = collector;
-      }
-
-      if (groupCommand instanceof Grouping.CommandQuery) {
-        int docsToCollect = groupCommand.docsPerGroup<0 ? maxDoc : groupCommand.groupOffset + groupCommand.docsPerGroup;
-        if (docsToCollect < 0 || docsToCollect > maxDoc) docsToCollect = maxDoc;
-
-        DocSet groupFilt = getDocSet(((Grouping.CommandQuery)groupCommand).query);
-        TopFieldCollector collector = TopFieldCollector.create(groupCommand.groupSort==null ? sort : groupCommand.groupSort, docsToCollect, false, needScores, needScores, true);
-        collectors.add(new FilterCollector(groupFilt, collector));
-      }
-    }
-
-    Collector allCollectors = MultiCollector.wrap(collectors.toArray(new Collector[collectors.size()]));
-    DocSetCollector setCollector = null;
-    if (getDocSet) {
-      // TODO: can callCollectors be zero length?
-      setCollector = new DocSetDelegateCollector(maxDoc()>>6, maxDoc(), allCollectors);
-      allCollectors = setCollector;
-    }
-
-    search(query, luceneFilter, allCollectors);
-
-    if (getDocSet) {
-      qr.docListAndSet.docSet = setCollector.getDocSet();
-    }
-
-    // TODO: make this a generic collector list
-    int numPhase2 = 0;
-    List<Phase2GroupCollector> phase2Collectors = new ArrayList<Phase2GroupCollector>(cmd.groupCommands.size());
-    for (Grouping.Command groupCommand : cmd.groupCommands) {
-      if (groupCommand instanceof Grouping.CommandFunc) {
-        Grouping.CommandFunc gc = (Grouping.CommandFunc)groupCommand;
-        Sort collectorSort = gc.groupSort == null ? sort : gc.groupSort;
-
-        int docsToCollect = groupCommand.docsPerGroup<0 ? maxDoc : groupCommand.groupOffset + groupCommand.docsPerGroup;
-        if (docsToCollect < 0 || docsToCollect > maxDoc) docsToCollect = maxDoc;
-
-        Phase2GroupCollector collector = new Phase2GroupCollector((TopGroupCollector)gc.collector, gc.groupBy, gc.context, collectorSort, docsToCollect, needScores, groupCommand.offset);
-        phase2Collectors.add(collector);
-        numPhase2++;
-      } else if (groupCommand instanceof Grouping.CommandQuery) {
-        phase2Collectors.add(null);
-      } else {
-        phase2Collectors.add(null);        
-      }
-    }
-
-    // TODO: optionally cache docs and feed them back through rather than re-searching
-    if (numPhase2 > 0)
-      search(query, luceneFilter, MultiCollector.wrap(phase2Collectors.toArray(new Collector[phase2Collectors.size()])));
-
-    Set<Integer> idSet = new LinkedHashSet<Integer>();  // used for tracking unique docs when we need a doclist
-    int maxMatches = 0;
-    float maxScore = Float.NEGATIVE_INFINITY;
-
-    NamedList grouped = new SimpleOrderedMap();
-    for (int cmdnum=0; cmdnum<cmd.groupCommands.size(); cmdnum++) {
-      Grouping.Command groupCommand = cmd.groupCommands.get(cmdnum);
-      GroupCollector gcollector = collectors.get(cmdnum);
-
-      NamedList groupResult = new SimpleOrderedMap();
-      grouped.add(groupCommand.key, groupResult);  // grouped={ key={
-
-      int this_matches = gcollector.getMatches();
-      groupResult.add("matches", this_matches);
-      maxMatches = Math.max(maxMatches, this_matches);
-
-      // TODO: refactor this
-      if (groupCommand instanceof Grouping.CommandQuery) {
-
-        int docsToCollect = groupCommand.docsPerGroup<0 ? maxDoc : groupCommand.groupOffset + groupCommand.docsPerGroup;
-        if (docsToCollect < 0 || docsToCollect > maxDoc) docsToCollect = maxDoc;
-
-        TopDocs topDocs = ((FilterCollector)gcollector).getTopFieldCollector().topDocs(0, docsToCollect);
-
-        // TODO: refactor
-
-        //topDocs.totalHits
-        int ids[] = new int[topDocs.scoreDocs.length];
-        float[] scores = needScores ? new float[topDocs.scoreDocs.length] : null;
-        for (int i=0; i<ids.length; i++) {
-          ids[i] = topDocs.scoreDocs[i].doc;
-          if (scores != null)
-            scores[i] = topDocs.scoreDocs[i].score;
-        }
-
-        float score = topDocs.getMaxScore();
-        maxScore = Math.max(maxScore, score);
-        DocSlice docs = new DocSlice(groupCommand.groupOffset, Math.max(0, ids.length - groupCommand.groupOffset), ids, scores, topDocs.totalHits, score);
-        groupResult.add("doclist", docs);
-
-        if (getDocList) {
-          DocIterator iter = docs.iterator();
-          while (iter.hasNext())
-            idSet.add(iter.nextDoc());
-        }
-
-        continue;
-      }
-
-      Grouping.CommandFunc groupCommandFunc = (Grouping.CommandFunc)groupCommand;
-      TopGroupCollector collector = (TopGroupCollector)gcollector;
-      Phase2GroupCollector collector2 = phase2Collectors.get(cmdnum);
-
-      if (collector.orderedGroups == null) collector.buildSet();
-
-      List groupList = new ArrayList();
-      groupResult.add("groups", groupList);        // grouped={ key={ groups=[
-
-      int skipCount = groupCommand.offset;
-      for (SearchGroup group : collector.orderedGroups) {
-        if (skipCount > 0) {
-          skipCount--;
-          continue;
-        }
-        NamedList nl = new SimpleOrderedMap();
-        groupList.add(nl);                         // grouped={ key={ groups=[ {
-
-        nl.add("groupValue", group.groupValue.toObject());
-
-        SearchGroupDocs groupDocs = collector2.groupMap.get(group.groupValue);
-        // nl.add("matches", groupDocs.matches);  // redundant with doclist.numFound from the doc list
-
-        int docsToCollect = groupCommand.docsPerGroup<0 ? maxDoc : groupCommand.groupOffset + groupCommand.docsPerGroup;
-        if (docsToCollect < 0 || docsToCollect > maxDoc) docsToCollect = maxDoc;
-
-        TopDocs topDocs = groupDocs.collector.topDocs(0, docsToCollect);
-        //topDocs.totalHits
-        int ids[] = new int[topDocs.scoreDocs.length];
-        float[] scores = needScores ? new float[topDocs.scoreDocs.length] : null;
-        for (int i=0; i<ids.length; i++) {
-          ids[i] = topDocs.scoreDocs[i].doc;
-          if (scores != null)
-            scores[i] = topDocs.scoreDocs[i].score;
-        }
-
-        float score = topDocs.getMaxScore();
-        maxScore = Math.max(maxScore, score);
-        DocSlice docs = new DocSlice(groupCommand.groupOffset, Math.max(0, ids.length - groupCommand.groupOffset), ids, scores, topDocs.totalHits, score);
-        nl.add("doclist", docs);
-
-        if (getDocList) {
-          DocIterator iter = docs.iterator();
-          while (iter.hasNext())
-            idSet.add(iter.nextDoc());
-        }
-        /*** values from stage 1
-         DocSlice docs = new DocSlice(0, 1, new int[] {group.topDoc}, null, 1, 0);
-         nl.add("docs", docs);
-
-         Object[] vals = new Object[collector.comparators.length];
-         for (int i=0; i<vals.length; i++) {
-         vals[i] = collector.comparators[i].value(group.comparatorSlot);
-         }
-         nl.add("groupSortValue", vals);
-         groupResult.add(nl);
-         ***/
-      }
-    }
-
-    qr.groupedResults = grouped;    
-
-    if (getDocList) {
-      int sz = idSet.size();
-      int[] ids = new int[sz];
-      int idx = 0;
-      for (int val : idSet) {
-        ids[idx++] = val;
-      }
-      qr.docListAndSet.docList = new DocSlice(0, sz, ids, null, maxMatches, maxScore);
-    }
-
-  }
-
   /**
    * getDocList version that uses+populates query and filter caches.
    * In the event of a timeout, the cache is not populated.
    */
   private void getDocListC(QueryResult qr, QueryCommand cmd) throws IOException {
-    if (cmd.groupCommands != null) {
-      groupBy(qr, cmd);
-      return;
-    }
-
     DocListAndSet out = new DocListAndSet();
     qr.setDocListAndSet(out);
     QueryResultKey key=null;
@@ -2025,7 +1806,7 @@ public class SolrIndexSearcher extends I
     private int flags;
     private long timeAllowed = -1;
 
-    public List<Grouping.Command> groupCommands;
+    // public List<Grouping.Command> groupCommands;
 
     public Query getQuery() { return query; }
     public QueryCommand setQuery(Query query) {

Modified: lucene/dev/trunk/solr/src/test/org/apache/solr/TestGroupingSearch.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/TestGroupingSearch.java?rev=1030220&r1=1030219&r2=1030220&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/TestGroupingSearch.java (original)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/TestGroupingSearch.java Tue Nov  2 21:09:10 2010
@@ -105,27 +105,6 @@ public class TestGroupingSearch extends 
             );
   }
 
-  @Test
-  public void testGroupingGroupSortingName() {
-    assertU(add(doc("id", "1","name", "author1", "title", "a book title")));
-    assertU(add(doc("id", "2","name", "author1", "title", "the title")));
-    assertU(add(doc("id", "3","name", "author2", "title", "book title")));
-    assertU(add(doc("id", "4","name", "author2", "title", "the title")));
-    assertU(commit());
-
-    assertQ(req("q","title:title", "group", "true", "group.field","name", "group.sort", "title asc")
-            ,"*[count(//arr[@name='groups']/lst) = 2]"
-            ,"//arr[@name='groups']/lst[1]/str[@name='groupValue'][.='author2']"
-    //       ,"//arr[@name='groups']/lst[1]/int[@name='matches'][.='2']"
-            ,"//arr[@name='groups']/lst[1]/result[@numFound='2']"
-            ,"//arr[@name='groups']/lst[1]/result/doc/*[@name='id'][.='3']"
-
-            ,"//arr[@name='groups']/lst[2]/str[@name='groupValue'][.='author1']"
-    //        ,"//arr[@name='groups']/lst[2]/int[@name='matches'][.='2']"
-            ,"//arr[@name='groups']/lst[2]/result[@numFound='2']"
-            ,"//arr[@name='groups']/lst[2]/result/doc/*[@name='id'][.='1']"
-            );
-  }
 
   @Test
   public void testGroupingGroupSortingWeight() {