SOLR-236: refactoring - use Lucene's new MultiCollector, remove ours, move GroupCommand out of SolrIndexSearcher

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@998343 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2010-09-17 21:46:58 +00:00
parent 634cf215f1
commit 17376b0fe3
3 changed files with 26 additions and 79 deletions

View File

@ -33,10 +33,8 @@ import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.schema.FieldType; import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.SchemaField; import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.*; import org.apache.solr.search.*;
import org.apache.solr.search.function.BoostedQuery;
import org.apache.solr.search.function.FunctionQuery; import org.apache.solr.search.function.FunctionQuery;
import org.apache.solr.search.function.QueryValueSource; import org.apache.solr.search.function.QueryValueSource;
import org.apache.solr.search.function.ValueSource;
import org.apache.solr.util.SolrPluginUtils; import org.apache.solr.util.SolrPluginUtils;
import java.io.IOException; import java.io.IOException;
@ -190,7 +188,7 @@ public class QueryComponent extends SearchComponent
boolean doGroup = params.getBool(GroupParams.GROUP, false); boolean doGroup = params.getBool(GroupParams.GROUP, false);
if (doGroup) { if (doGroup) {
try { try {
cmd.groupCommands = new ArrayList<SolrIndexSearcher.GroupCommand>(); cmd.groupCommands = new ArrayList<Grouping.Command>();
String[] fields = params.getParams(GroupParams.GROUP_FIELD); String[] fields = params.getParams(GroupParams.GROUP_FIELD);
String[] funcs = params.getParams(GroupParams.GROUP_FUNC); String[] funcs = params.getParams(GroupParams.GROUP_FUNC);
@ -217,7 +215,7 @@ public class QueryComponent extends SearchComponent
for (String groupByStr : funcs) { for (String groupByStr : funcs) {
QParser parser = QParser.getParser(groupByStr, "func", rb.req); QParser parser = QParser.getParser(groupByStr, "func", rb.req);
Query q = parser.getQuery(); Query q = parser.getQuery();
SolrIndexSearcher.GroupCommandFunc gc = new SolrIndexSearcher.GroupCommandFunc(); Grouping.CommandFunc gc = new Grouping.CommandFunc();
gc.groupSort = groupSort; gc.groupSort = groupSort;
if (q instanceof FunctionQuery) { if (q instanceof FunctionQuery) {

View File

@ -25,66 +25,30 @@ import org.apache.solr.search.function.ValueSource;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
public class MultiCollector extends Collector { public class Grouping {
final Collector[] collectors;
final boolean acceptsDocsOutOfOrder;
public static Collector wrap(List<? extends Collector> collectors) { public static class Command {
return collectors.size() == 1 ? collectors.get(0) : new MultiCollector(collectors); 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 int groupLimit; // how many groups - defaults to the "rows" parameter
public int docsPerGroup; // how many docs in each group - from "group.limit" param, default=1
} }
public static Collector[] subCollectors(Collector collector) { public static class CommandQuery extends Command {
if (collector instanceof MultiCollector) public Query query;
return ((MultiCollector)collector).collectors;
return new Collector[]{collector};
} }
public MultiCollector(List<? extends Collector> collectors) { public static class CommandFunc extends Command {
this(collectors.toArray(new Collector[collectors.size()])); public ValueSource groupBy;
}
public MultiCollector(Collector[] collectors) {
this.collectors = collectors;
boolean acceptsDocsOutOfOrder = true; // todo - find a better place to store these
for (Collector collector : collectors) { transient Map context;
if (collector.acceptsDocsOutOfOrder() == false) { transient Collector collector;
acceptsDocsOutOfOrder = false;
break;
}
}
this.acceptsDocsOutOfOrder = acceptsDocsOutOfOrder;
}
@Override
public void setScorer(Scorer scorer) throws IOException {
for (Collector collector : collectors)
collector.setScorer(scorer);
}
@Override
public void collect(int doc) throws IOException {
for (Collector collector : collectors)
collector.collect(doc);
}
@Override
public void setNextReader(IndexReader reader, int docBase) throws IOException {
for (Collector collector : collectors)
collector.setNextReader(reader, docBase);
}
@Override
public boolean acceptsDocsOutOfOrder() {
return acceptsDocsOutOfOrder;
} }
} }
class SearchGroup { class SearchGroup {
public MutableValue groupValue; public MutableValue groupValue;
int matches; int matches;

View File

@ -923,10 +923,10 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean {
// TODO: make this a generic collector list // TODO: make this a generic collector list
List<TopGroupCollector> collectors = new ArrayList<TopGroupCollector>(cmd.groupCommands.size()); List<TopGroupCollector> collectors = new ArrayList<TopGroupCollector>(cmd.groupCommands.size());
for (GroupCommand groupCommand : cmd.groupCommands) { for (Grouping.Command groupCommand : cmd.groupCommands) {
// TODO: perhaps use some methods rather than instanceof // TODO: perhaps use some methods rather than instanceof
if (groupCommand instanceof GroupCommandFunc) { if (groupCommand instanceof Grouping.CommandFunc) {
GroupCommandFunc gc = (GroupCommandFunc)groupCommand; Grouping.CommandFunc gc = (Grouping.CommandFunc)groupCommand;
Map context = ValueSource.newContext(); Map context = ValueSource.newContext();
gc.groupBy.createWeight(context, this); gc.groupBy.createWeight(context, this);
TopGroupCollector collector; TopGroupCollector collector;
@ -943,7 +943,7 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean {
} }
} }
Collector allCollectors = MultiCollector.wrap(collectors); Collector allCollectors = MultiCollector.wrap(collectors.toArray(new Collector[collectors.size()]));
DocSetCollector setCollector = null; DocSetCollector setCollector = null;
if (getDocSet) { if (getDocSet) {
// TODO: can callCollectors be zero length? // TODO: can callCollectors be zero length?
@ -959,9 +959,9 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean {
// TODO: make this a generic collector list // TODO: make this a generic collector list
List<Phase2GroupCollector> phase2Collectors = new ArrayList<Phase2GroupCollector>(cmd.groupCommands.size()); List<Phase2GroupCollector> phase2Collectors = new ArrayList<Phase2GroupCollector>(cmd.groupCommands.size());
for (GroupCommand groupCommand : cmd.groupCommands) { for (Grouping.Command groupCommand : cmd.groupCommands) {
if (groupCommand instanceof GroupCommandFunc) { if (groupCommand instanceof Grouping.CommandFunc) {
GroupCommandFunc gc = (GroupCommandFunc)groupCommand; Grouping.CommandFunc gc = (Grouping.CommandFunc)groupCommand;
Sort collectorSort = gc.groupSort == null ? sort : gc.groupSort; Sort collectorSort = gc.groupSort == null ? sort : gc.groupSort;
Phase2GroupCollector collector = new Phase2GroupCollector((TopGroupCollector)gc.collector, gc.groupBy, gc.context, collectorSort, gc.docsPerGroup, needScores); Phase2GroupCollector collector = new Phase2GroupCollector((TopGroupCollector)gc.collector, gc.groupBy, gc.context, collectorSort, gc.docsPerGroup, needScores);
phase2Collectors.add(collector); phase2Collectors.add(collector);
@ -969,7 +969,7 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean {
} }
// TODO: optionally cache docs and feed them back through rather than re-searching // TODO: optionally cache docs and feed them back through rather than re-searching
search(query, luceneFilter, MultiCollector.wrap(phase2Collectors)); 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 Set<Integer> idSet = new LinkedHashSet<Integer>(); // used for tracking unique docs when we need a doclist
int maxMatches = 0; int maxMatches = 0;
@ -977,8 +977,8 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean {
NamedList grouped = new SimpleOrderedMap(); NamedList grouped = new SimpleOrderedMap();
for (int cmdnum=0; cmdnum<cmd.groupCommands.size(); cmdnum++) { for (int cmdnum=0; cmdnum<cmd.groupCommands.size(); cmdnum++) {
GroupCommand groupCommand = cmd.groupCommands.get(cmdnum); Grouping.Command groupCommand = cmd.groupCommands.get(cmdnum);
GroupCommandFunc groupCommandFunc = (GroupCommandFunc)groupCommand; Grouping.CommandFunc groupCommandFunc = (Grouping.CommandFunc)groupCommand;
TopGroupCollector collector = collectors.get(cmdnum); TopGroupCollector collector = collectors.get(cmdnum);
Phase2GroupCollector collector2 = phase2Collectors.get(cmdnum); Phase2GroupCollector collector2 = phase2Collectors.get(cmdnum);
@ -1871,7 +1871,7 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean {
private int flags; private int flags;
private long timeAllowed = -1; private long timeAllowed = -1;
public List<GroupCommand> groupCommands; public List<Grouping.Command> groupCommands;
public Query getQuery() { return query; } public Query getQuery() { return query; }
public QueryCommand setQuery(Query query) { public QueryCommand setQuery(Query query) {
@ -1973,21 +1973,6 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean {
} }
} }
public static class GroupCommand {
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 int groupLimit; // how many groups - defaults to the "rows" parameter
public int docsPerGroup; // how many docs in each group - from "group.limit" param, default=1
}
public static class GroupCommandFunc extends GroupCommand {
public ValueSource groupBy;
// todo - find a better place to store these
transient Map context;
transient Collector collector;
}
/** /**
* The result of a search. * The result of a search.