diff --git lucene/facet/src/java/org/apache/lucene/facet/range/RangeAccumulator.java lucene/facet/src/java/org/apache/lucene/facet/range/RangeAccumulator.java index 6adacec..6a9f2f8 100644 --- lucene/facet/src/java/org/apache/lucene/facet/range/RangeAccumulator.java +++ lucene/facet/src/java/org/apache/lucene/facet/range/RangeAccumulator.java @@ -28,9 +28,8 @@ import org.apache.lucene.facet.search.FacetResult; import org.apache.lucene.facet.search.FacetResultNode; import org.apache.lucene.facet.search.FacetsAccumulator; import org.apache.lucene.facet.search.FacetsCollector.MatchingDocs; -import org.apache.lucene.facet.taxonomy.CategoryPath; import org.apache.lucene.index.NumericDocValues; -import org.apache.lucene.util.Bits; +import org.apache.lucene.queries.function.FunctionValues; /** Uses a {@link NumericDocValues} and accumulates * counts for provided ranges. This is dynamic (does not @@ -39,18 +38,6 @@ import org.apache.lucene.util.Bits; public class RangeAccumulator extends FacetsAccumulator { - static class RangeSet { - final Range[] ranges; - final String field; - - public RangeSet(Range[] ranges, String field) { - this.ranges = ranges; - this.field = field; - } - } - - final List requests = new ArrayList(); - public RangeAccumulator(FacetRequest... facetRequests) { this(Arrays.asList(facetRequests)); } @@ -65,9 +52,6 @@ public class RangeAccumulator extends FacetsAccumulator { if (fr.categoryPath.length != 1) { throw new IllegalArgumentException("only flat (dimension only) CategoryPath is allowed"); } - - RangeFacetRequest rfr = (RangeFacetRequest) fr; - requests.add(new RangeSet(rfr.ranges, fr.categoryPath.components[0])); } } @@ -78,35 +62,29 @@ public class RangeAccumulator extends FacetsAccumulator { // faster to do MachingDocs on the inside) ... see // patches on LUCENE-4965): List results = new ArrayList(); - for (int i = 0; i < requests.size(); i++) { - RangeSet ranges = requests.get(i); - - int[] counts = new int[ranges.ranges.length]; + for (FacetRequest req : searchParams.facetRequests) { + RangeFacetRequest rangeFR = (RangeFacetRequest) req; + int[] counts = new int[rangeFR.ranges.length]; for (MatchingDocs hits : matchingDocs) { - NumericDocValues ndv = hits.context.reader().getNumericDocValues(ranges.field); - if (ndv == null) { - continue; // no numeric values for this field in this reader - } - Bits docsWithField = hits.context.reader().getDocsWithField(ranges.field); - + FunctionValues fv = rangeFR.getValues(hits.context); final int length = hits.bits.length(); int doc = 0; while (doc < length && (doc = hits.bits.nextSetBit(doc)) != -1) { - long v = ndv.get(doc); - // Skip missing docs: - if (v == 0 && docsWithField.get(doc) == false) { - doc++; + if (!fv.exists(doc)) { + ++doc; continue; } + + long v = fv.longVal(doc); // TODO: if all ranges are non-overlapping, we // should instead do a bin-search up front // (really, a specialized case of the interval // tree) // TODO: use interval tree instead of linear search: - for (int j = 0; j < ranges.ranges.length; j++) { - if (ranges.ranges[j].accept(v)) { + for (int j = 0; j < rangeFR.ranges.length; j++) { + if (rangeFR.ranges[j].accept(v)) { counts[j]++; } } @@ -114,19 +92,19 @@ public class RangeAccumulator extends FacetsAccumulator { doc++; } } - - List nodes = new ArrayList(ranges.ranges.length); - for(int j=0;j nodes = new ArrayList(rangeFR.ranges.length); + for (int j = 0; j < rangeFR.ranges.length; j++) { + nodes.add(new RangeFacetResultNode(rangeFR.label, rangeFR.ranges[j], counts[j])); } - + FacetResultNode rootNode = new FacetResultNode(-1, 0); - rootNode.label = new CategoryPath(ranges.field); + rootNode.label = rangeFR.categoryPath; rootNode.subResults = nodes; - results.add(new FacetResult(searchParams.facetRequests.get(i), rootNode, nodes.size())); + results.add(new FacetResult(req, rootNode, nodes.size())); } - + return results; } diff --git lucene/facet/src/java/org/apache/lucene/facet/range/RangeFacetRequest.java lucene/facet/src/java/org/apache/lucene/facet/range/RangeFacetRequest.java index a7376f7..15db37b 100644 --- lucene/facet/src/java/org/apache/lucene/facet/range/RangeFacetRequest.java +++ lucene/facet/src/java/org/apache/lucene/facet/range/RangeFacetRequest.java @@ -17,12 +17,18 @@ package org.apache.lucene.facet.range; * limitations under the License. */ +import java.io.IOException; +import java.util.Collections; import java.util.List; import org.apache.lucene.facet.params.FacetIndexingParams; import org.apache.lucene.facet.search.FacetRequest; import org.apache.lucene.facet.search.FacetsAggregator; import org.apache.lucene.facet.taxonomy.CategoryPath; +import org.apache.lucene.index.AtomicReaderContext; +import org.apache.lucene.queries.function.FunctionValues; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.lucene.queries.function.valuesource.LongFieldSource; /** * Facet request for dynamic ranges based on a @@ -33,19 +39,41 @@ import org.apache.lucene.facet.taxonomy.CategoryPath; */ public class RangeFacetRequest extends FacetRequest { + // nocommit jdocs for class + ctors + public final Range[] ranges; - + public final String label; + + private final ValueSource valueSource; + @SuppressWarnings("unchecked") public RangeFacetRequest(String field, T...ranges) { - super(new CategoryPath(field), 1); - this.ranges = ranges; + this(field, new LongFieldSource(field), ranges); } @SuppressWarnings("unchecked") public RangeFacetRequest(String field, List ranges) { this(field, (T[]) ranges.toArray(new Range[ranges.size()])); } + + @SuppressWarnings("unchecked") + public RangeFacetRequest(String label, ValueSource valueSource, T...ranges) { + super(new CategoryPath(label), 1); + this.ranges = ranges; + this.valueSource = valueSource; + this.label = label; + } + + @SuppressWarnings("unchecked") + public RangeFacetRequest(String label, ValueSource valueSource, List ranges) { + this(label, valueSource, (T[]) ranges.toArray(new Range[ranges.size()])); + } + // nocommit jdocs + public FunctionValues getValues(AtomicReaderContext context) throws IOException { + return valueSource.getValues(Collections.emptyMap(), context); + } + @Override public FacetsAggregator createFacetsAggregator(FacetIndexingParams fip) { return null;