mirror of https://github.com/apache/lucene.git
SOLR-9026: add facet telemetry for legacy facets
This commit is contained in:
parent
30cbab6793
commit
b42945ea92
|
@ -126,6 +126,10 @@ New Features
|
|||
|
||||
* SOLR-8972: Add GraphHandler and GraphMLResponseWriter to support graph visualizations (Joel Bernstein)
|
||||
|
||||
* SOLR-9026: Extend facet telemetry support to legacy (non-json) facets under "debug/facet-debug" in
|
||||
the response. (Michael Sun, yonik)
|
||||
|
||||
|
||||
Bug Fixes
|
||||
----------------------
|
||||
|
||||
|
|
|
@ -114,6 +114,11 @@ public class DebugComponent extends SearchComponent
|
|||
if (fdebug != null) {
|
||||
info.add("facet-trace", fdebug.getFacetDebugInfo());
|
||||
}
|
||||
|
||||
fdebug = (FacetDebugInfo)(rb.req.getContext().get("FacetDebugInfo-nonJson"));
|
||||
if (fdebug != null) {
|
||||
info.add("facet-debug", fdebug.getFacetDebugInfo());
|
||||
}
|
||||
|
||||
if (rb.req.getJSON() != null) {
|
||||
info.add(JSON, rb.req.getJSON());
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.net.URL;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
@ -50,6 +49,8 @@ import org.apache.solr.request.SolrQueryRequest;
|
|||
import org.apache.solr.schema.FieldType;
|
||||
import org.apache.solr.search.QueryParsing;
|
||||
import org.apache.solr.search.SyntaxError;
|
||||
import org.apache.solr.search.facet.FacetDebugInfo;
|
||||
import org.apache.solr.util.RTimer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -252,7 +253,16 @@ public class FacetComponent extends SearchComponent {
|
|||
SolrParams params = rb.req.getParams();
|
||||
SimpleFacets f = new SimpleFacets(rb.req, rb.getResults().docSet, params, rb);
|
||||
|
||||
NamedList<Object> counts = FacetComponent.getFacetCounts(f);
|
||||
RTimer timer = null;
|
||||
FacetDebugInfo fdebug = null;
|
||||
|
||||
if (rb.isDebug()) {
|
||||
fdebug = new FacetDebugInfo();
|
||||
rb.req.getContext().put("FacetDebugInfo-nonJson", fdebug);
|
||||
timer = new RTimer();
|
||||
}
|
||||
|
||||
NamedList<Object> counts = FacetComponent.getFacetCounts(f, fdebug);
|
||||
String[] pivots = params.getParams(FacetParams.FACET_PIVOT);
|
||||
if (!ArrayUtils.isEmpty(pivots)) {
|
||||
PivotFacetProcessor pivotProcessor
|
||||
|
@ -264,10 +274,19 @@ public class FacetComponent extends SearchComponent {
|
|||
}
|
||||
}
|
||||
|
||||
if (fdebug != null) {
|
||||
long timeElapsed = (long) timer.getTime();
|
||||
fdebug.setElapse(timeElapsed);
|
||||
}
|
||||
|
||||
rb.rsp.add("facet_counts", counts);
|
||||
}
|
||||
}
|
||||
|
||||
public static NamedList<Object> getFacetCounts(SimpleFacets simpleFacets) {
|
||||
return getFacetCounts(simpleFacets, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks at various Params to determining if any simple Facet Constraint count
|
||||
* computations are desired.
|
||||
|
@ -279,7 +298,7 @@ public class FacetComponent extends SearchComponent {
|
|||
* @see FacetParams#FACET
|
||||
* @return a NamedList of Facet Count info or null
|
||||
*/
|
||||
public static NamedList<Object> getFacetCounts(SimpleFacets simpleFacets) {
|
||||
public static NamedList<Object> getFacetCounts(SimpleFacets simpleFacets, FacetDebugInfo fdebug) {
|
||||
// if someone called this method, benefit of the doubt: assume true
|
||||
if (!simpleFacets.getGlobalParams().getBool(FacetParams.FACET, true))
|
||||
return null;
|
||||
|
@ -288,7 +307,19 @@ public class FacetComponent extends SearchComponent {
|
|||
NamedList<Object> counts = new SimpleOrderedMap<>();
|
||||
try {
|
||||
counts.add(FACET_QUERY_KEY, simpleFacets.getFacetQueryCounts());
|
||||
counts.add(FACET_FIELD_KEY, simpleFacets.getFacetFieldCounts());
|
||||
if (fdebug != null) {
|
||||
FacetDebugInfo fd = new FacetDebugInfo();
|
||||
fd.putInfoItem("action", "field facet");
|
||||
fd.setProcessor(simpleFacets.getClass().getSimpleName());
|
||||
fdebug.addChild(fd);
|
||||
simpleFacets.setFacetDebugInfo(fd);
|
||||
final RTimer timer = new RTimer();
|
||||
counts.add(FACET_FIELD_KEY, simpleFacets.getFacetFieldCounts());
|
||||
long timeElapsed = (long) timer.getTime();
|
||||
fd.setElapse(timeElapsed);
|
||||
} else {
|
||||
counts.add(FACET_FIELD_KEY, simpleFacets.getFacetFieldCounts());
|
||||
}
|
||||
counts.add(FACET_RANGES_KEY, rangeFacetProcessor.getFacetRangeCounts());
|
||||
counts.add(FACET_INTERVALS_KEY, simpleFacets.getFacetIntervalCounts());
|
||||
counts.add(SpatialHeatmapFacets.RESPONSE_KEY, simpleFacets.getHeatmapCounts());
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
*/
|
||||
package org.apache.solr.request;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.index.DocValues;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.MultiDocValues.MultiSortedDocValues;
|
||||
|
@ -37,11 +40,9 @@ import org.apache.solr.schema.SchemaField;
|
|||
import org.apache.solr.search.DocSet;
|
||||
import org.apache.solr.search.Filter;
|
||||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.search.facet.FacetDebugInfo;
|
||||
import org.apache.solr.util.LongPriorityQueue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Computes term facets for docvalues field (single or multivalued).
|
||||
* <p>
|
||||
|
@ -57,7 +58,7 @@ import java.util.List;
|
|||
public class DocValuesFacets {
|
||||
private DocValuesFacets() {}
|
||||
|
||||
public static NamedList<Integer> getCounts(SolrIndexSearcher searcher, DocSet docs, String fieldName, int offset, int limit, int mincount, boolean missing, String sort, String prefix, String contains, boolean ignoreCase) throws IOException {
|
||||
public static NamedList<Integer> getCounts(SolrIndexSearcher searcher, DocSet docs, String fieldName, int offset, int limit, int mincount, boolean missing, String sort, String prefix, String contains, boolean ignoreCase, FacetDebugInfo fdebug) throws IOException {
|
||||
SchemaField schemaField = searcher.getSchema().getField(fieldName);
|
||||
FieldType ft = schemaField.getType();
|
||||
NamedList<Integer> res = new NamedList<>();
|
||||
|
@ -118,6 +119,9 @@ public class DocValuesFacets {
|
|||
// count collection array only needs to be as big as the number of terms we are
|
||||
// going to collect counts for.
|
||||
final int[] counts = new int[nTerms];
|
||||
if (fdebug != null) {
|
||||
fdebug.putInfoItem("numBuckets", nTerms);
|
||||
}
|
||||
|
||||
Filter filter = docs.getTopFilter();
|
||||
List<LeafReaderContext> leaves = searcher.getTopReaderContext().leaves();
|
||||
|
|
|
@ -16,6 +16,24 @@
|
|||
*/
|
||||
package org.apache.solr.request;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.RunnableFuture;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.lucene.index.Fields;
|
||||
import org.apache.lucene.index.LeafReader;
|
||||
|
@ -49,7 +67,6 @@ import org.apache.solr.common.util.ExecutorUtil;
|
|||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||
import org.apache.solr.common.util.StrUtils;
|
||||
import org.apache.solr.handler.component.FacetComponent;
|
||||
import org.apache.solr.handler.component.ResponseBuilder;
|
||||
import org.apache.solr.handler.component.SpatialHeatmapFacets;
|
||||
import org.apache.solr.request.IntervalFacets.FacetInterval;
|
||||
|
@ -69,28 +86,12 @@ import org.apache.solr.search.QueryParsing;
|
|||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.search.SortedIntDocSet;
|
||||
import org.apache.solr.search.SyntaxError;
|
||||
import org.apache.solr.search.facet.FacetDebugInfo;
|
||||
import org.apache.solr.search.facet.FacetProcessor;
|
||||
import org.apache.solr.search.grouping.GroupingSpecification;
|
||||
import org.apache.solr.util.BoundedTreeSet;
|
||||
import org.apache.solr.util.DefaultSolrThreadFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.RunnableFuture;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.solr.util.RTimer;
|
||||
|
||||
/**
|
||||
* A class that generates simple Facet information for a request.
|
||||
|
@ -109,6 +110,9 @@ public class SimpleFacets {
|
|||
protected final SolrQueryRequest req;
|
||||
protected final ResponseBuilder rb;
|
||||
|
||||
protected FacetDebugInfo fdebugParent;
|
||||
protected FacetDebugInfo fdebug;
|
||||
|
||||
// per-facet values
|
||||
protected final static class ParsedParams {
|
||||
final public SolrParams localParams; // localParams on this particular facet command
|
||||
|
@ -160,6 +164,10 @@ public class SimpleFacets {
|
|||
this.rb = rb;
|
||||
}
|
||||
|
||||
public void setFacetDebugInfo(FacetDebugInfo fdebugParent) {
|
||||
this.fdebugParent = fdebugParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if a String contains the given substring. Otherwise
|
||||
* <code>false</code>.
|
||||
|
@ -450,6 +458,14 @@ public class SimpleFacets {
|
|||
method = FacetMethod.FC;
|
||||
}
|
||||
|
||||
RTimer timer = null;
|
||||
if (fdebug != null) {
|
||||
fdebug.putInfoItem("method", method.name());
|
||||
fdebug.putInfoItem("inputDocSetSize", docs.size());
|
||||
fdebug.putInfoItem("field", field);
|
||||
timer = new RTimer();
|
||||
}
|
||||
|
||||
if (params.getFieldBool(field, GroupParams.GROUP_FACET, false)) {
|
||||
counts = getGroupedCounts(searcher, docs, field, multiToken, offset,limit, mincount, missing, sort, prefix, contains, ignoreCase);
|
||||
} else {
|
||||
|
@ -535,13 +551,18 @@ public class SimpleFacets {
|
|||
}
|
||||
break;
|
||||
case FC:
|
||||
counts = DocValuesFacets.getCounts(searcher, docs, field, offset,limit, mincount, missing, sort, prefix, contains, ignoreCase);
|
||||
counts = DocValuesFacets.getCounts(searcher, docs, field, offset,limit, mincount, missing, sort, prefix, contains, ignoreCase, fdebug);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
if (fdebug != null) {
|
||||
long timeElapsed = (long) timer.getTime();
|
||||
fdebug.setElapse(timeElapsed);
|
||||
}
|
||||
|
||||
return counts;
|
||||
}
|
||||
|
||||
|
@ -654,9 +675,17 @@ public class SimpleFacets {
|
|||
final Semaphore semaphore = new Semaphore((maxThreads <= 0) ? Integer.MAX_VALUE : maxThreads);
|
||||
List<Future<NamedList>> futures = new ArrayList<>(facetFs.length);
|
||||
|
||||
if (fdebugParent != null) {
|
||||
fdebugParent.putInfoItem("maxThreads", maxThreads);
|
||||
}
|
||||
|
||||
try {
|
||||
//Loop over fields; submit to executor, keeping the future
|
||||
for (String f : facetFs) {
|
||||
if (fdebugParent != null) {
|
||||
fdebug = new FacetDebugInfo();
|
||||
fdebugParent.addChild(fdebug);
|
||||
}
|
||||
final ParsedParams parsed = parseParams(FacetParams.FACET_FIELD, f);
|
||||
final SolrParams localParams = parsed.localParams;
|
||||
final String termList = localParams == null ? null : localParams.get(CommonParams.TERMS);
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.apache.solr.common.util.SimpleOrderedMap;
|
|||
|
||||
public class FacetDebugInfo {
|
||||
String processor;
|
||||
long elapse;
|
||||
long elapse = -1;
|
||||
String filter;
|
||||
Map<String, Object> info; // additional information
|
||||
final List<FacetDebugInfo> children;
|
||||
|
@ -69,8 +69,8 @@ public class FacetDebugInfo {
|
|||
SimpleOrderedMap<Object> info = new SimpleOrderedMap<>();
|
||||
|
||||
if (filter != null) info.add("filter", filter);
|
||||
info.add("processor", processor);
|
||||
info.add("elapse", elapse);
|
||||
if (processor != null) info.add("processor", processor);
|
||||
if (elapse != -1) info.add("elapse", elapse);
|
||||
if (reqDescription != null) {
|
||||
info.addAll(reqDescription);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue