mirror of https://github.com/apache/lucene.git
LUCENE-7610: Deprecate ValueSource methods in facets module
This commit is contained in:
parent
8b055382d6
commit
713b65d1dc
|
@ -79,6 +79,9 @@ API Changes
|
|||
replaced with Expression#getDoubleValuesSource(). (Alan Woodward, Adrien
|
||||
Grand)
|
||||
|
||||
* LUCENE-7610: The facets module now uses the DoubleValuesSource API, and
|
||||
methods that take ValueSource parameters are deprecated (Alan Woodward)
|
||||
|
||||
New features
|
||||
|
||||
* LUCENE-5867: Added BooleanSimilarity. (Robert Muir, Adrien Grand)
|
||||
|
|
|
@ -16,9 +16,13 @@
|
|||
*/
|
||||
package org.apache.lucene.demo.facet;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
|
||||
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
|
||||
import org.apache.lucene.document.DoublePoint;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.DoublePoint;
|
||||
import org.apache.lucene.document.NumericDocValuesField;
|
||||
import org.apache.lucene.expressions.Expression;
|
||||
import org.apache.lucene.expressions.SimpleBindings;
|
||||
|
@ -36,9 +40,9 @@ import org.apache.lucene.index.DirectoryReader;
|
|||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
|
@ -48,10 +52,6 @@ import org.apache.lucene.store.Directory;
|
|||
import org.apache.lucene.store.RAMDirectory;
|
||||
import org.apache.lucene.util.SloppyMath;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
|
||||
/** Shows simple usage of dynamic range faceting, using the
|
||||
* expressions module to calculate distance. */
|
||||
public class DistanceFacetsExample implements Closeable {
|
||||
|
@ -117,7 +117,7 @@ public class DistanceFacetsExample implements Closeable {
|
|||
writer.close();
|
||||
}
|
||||
|
||||
private ValueSource getDistanceValueSource() {
|
||||
private DoubleValuesSource getDistanceValueSource() {
|
||||
Expression distance;
|
||||
try {
|
||||
distance = JavascriptCompiler.compile(
|
||||
|
@ -130,7 +130,7 @@ public class DistanceFacetsExample implements Closeable {
|
|||
bindings.add(new SortField("latitude", SortField.Type.DOUBLE));
|
||||
bindings.add(new SortField("longitude", SortField.Type.DOUBLE));
|
||||
|
||||
return distance.getValueSource(bindings);
|
||||
return distance.getDoubleValuesSource(bindings);
|
||||
}
|
||||
|
||||
/** Given a latitude and longitude (in degrees) and the
|
||||
|
@ -224,7 +224,7 @@ public class DistanceFacetsExample implements Closeable {
|
|||
// Passing no baseQuery means we drill down on all
|
||||
// documents ("browse only"):
|
||||
DrillDownQuery q = new DrillDownQuery(null);
|
||||
final ValueSource vs = getDistanceValueSource();
|
||||
final DoubleValuesSource vs = getDistanceValueSource();
|
||||
q.add("field", range.getQuery(getBoundingBoxQuery(ORIGIN_LATITUDE, ORIGIN_LONGITUDE, range.max), vs));
|
||||
DrillSideways ds = new DrillSideways(searcher, config, (TaxonomyReader) null) {
|
||||
@Override
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
*
|
||||
* <li> Range faceting {@link org.apache.lucene.facet.range.LongRangeFacetCounts}, {@link
|
||||
* org.apache.lucene.facet.range.DoubleRangeFacetCounts} compute counts for a dynamic numeric
|
||||
* range from a provided {@link org.apache.lucene.queries.function.ValueSource} (previously indexed
|
||||
* range from a provided {@link org.apache.lucene.search.LongValuesSource} (previously indexed
|
||||
* numeric field, or a dynamic expression such as distance).
|
||||
* </ul>
|
||||
* <p>
|
||||
|
|
|
@ -17,16 +17,16 @@
|
|||
package org.apache.lucene.facet.range;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.search.ConstantScoreScorer;
|
||||
import org.apache.lucene.search.ConstantScoreWeight;
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
|
@ -95,9 +95,9 @@ public final class DoubleRange extends Range {
|
|||
private static class ValueSourceQuery extends Query {
|
||||
private final DoubleRange range;
|
||||
private final Query fastMatchQuery;
|
||||
private final ValueSource valueSource;
|
||||
private final DoubleValuesSource valueSource;
|
||||
|
||||
ValueSourceQuery(DoubleRange range, Query fastMatchQuery, ValueSource valueSource) {
|
||||
ValueSourceQuery(DoubleRange range, Query fastMatchQuery, DoubleValuesSource valueSource) {
|
||||
this.range = range;
|
||||
this.fastMatchQuery = fastMatchQuery;
|
||||
this.valueSource = valueSource;
|
||||
|
@ -158,11 +158,11 @@ public final class DoubleRange extends Range {
|
|||
approximation = s.iterator();
|
||||
}
|
||||
|
||||
final FunctionValues values = valueSource.getValues(Collections.emptyMap(), context);
|
||||
final DoubleValues values = valueSource.getValues(context, null);
|
||||
final TwoPhaseIterator twoPhase = new TwoPhaseIterator(approximation) {
|
||||
@Override
|
||||
public boolean matches() throws IOException {
|
||||
return range.accept(values.doubleVal(approximation.docID()));
|
||||
return values.advanceExact(approximation.docID()) && range.accept(values.doubleValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -177,8 +177,27 @@ public final class DoubleRange extends Range {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* @deprecated Use {@link #getQuery(Query, DoubleValuesSource)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Query getQuery(final Query fastMatchQuery, final ValueSource valueSource) {
|
||||
return new ValueSourceQuery(this, fastMatchQuery, valueSource.asDoubleValuesSource());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Query that matches documents in this range
|
||||
*
|
||||
* The query will check all documents that match the provided match query,
|
||||
* or every document in the index if the match query is null.
|
||||
*
|
||||
* If the value source is static, eg an indexed numeric field, it may be
|
||||
* faster to use {@link org.apache.lucene.search.PointRangeQuery}
|
||||
*
|
||||
* @param fastMatchQuery a query to use as a filter
|
||||
* @param valueSource the source of values for the range check
|
||||
*/
|
||||
public Query getQuery(Query fastMatchQuery, DoubleValuesSource valueSource) {
|
||||
return new ValueSourceQuery(this, fastMatchQuery, valueSource);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,22 +17,18 @@
|
|||
package org.apache.lucene.facet.range;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.document.DoubleDocValuesField; // javadocs
|
||||
import org.apache.lucene.document.FloatDocValuesField; // javadocs
|
||||
import org.apache.lucene.document.FloatDocValuesField;
|
||||
import org.apache.lucene.facet.Facets;
|
||||
import org.apache.lucene.facet.FacetsCollector.MatchingDocs;
|
||||
import org.apache.lucene.facet.FacetsCollector;
|
||||
import org.apache.lucene.facet.FacetsCollector.MatchingDocs;
|
||||
import org.apache.lucene.index.IndexReaderContext;
|
||||
import org.apache.lucene.index.ReaderUtil;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
|
||||
import org.apache.lucene.queries.function.valuesource.FloatFieldSource; // javadocs
|
||||
import org.apache.lucene.search.DocIdSet;
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
|
@ -41,46 +37,70 @@ import org.apache.lucene.util.NumericUtils;
|
|||
|
||||
/** {@link Facets} implementation that computes counts for
|
||||
* dynamic double ranges from a provided {@link
|
||||
* ValueSource}, using {@link FunctionValues#doubleVal}. Use
|
||||
* this for dimensions that change in real-time (e.g. a
|
||||
* DoubleValuesSource}. Use this for dimensions that change in real-time (e.g. a
|
||||
* relative time based dimension like "Past day", "Past 2
|
||||
* days", etc.) or that change for each request (e.g.
|
||||
* distance from the user's location, "< 1 km", "< 2 km",
|
||||
* etc.).
|
||||
*
|
||||
* <p> If you had indexed your field using {@link
|
||||
* FloatDocValuesField} then pass {@link FloatFieldSource}
|
||||
* as the {@link ValueSource}; if you used {@link
|
||||
* DoubleDocValuesField} then pass {@link
|
||||
* DoubleFieldSource} (this is the default used when you
|
||||
* pass just a the field name).
|
||||
* If you have indexed your field using {@link
|
||||
* FloatDocValuesField}, then you should use a DoubleValuesSource
|
||||
* generated from {@link DoubleValuesSource#fromFloatField(String)}.
|
||||
*
|
||||
* @lucene.experimental */
|
||||
public class DoubleRangeFacetCounts extends RangeFacetCounts {
|
||||
|
||||
/** Create {@code RangeFacetCounts}, using {@link
|
||||
* DoubleFieldSource} from the specified field. */
|
||||
/**
|
||||
* Create {@code RangeFacetCounts}, using {@link DoubleValues} from the specified field.
|
||||
*
|
||||
* N.B This assumes that the field was indexed with {@link org.apache.lucene.document.DoubleDocValuesField}.
|
||||
* For float-valued fields, use {@link #DoubleRangeFacetCounts(String, DoubleValuesSource, FacetsCollector, DoubleRange...)}
|
||||
*/
|
||||
public DoubleRangeFacetCounts(String field, FacetsCollector hits, DoubleRange... ranges) throws IOException {
|
||||
this(field, new DoubleFieldSource(field), hits, ranges);
|
||||
this(field, DoubleValuesSource.fromDoubleField(field), hits, ranges);
|
||||
}
|
||||
|
||||
/** Create {@code RangeFacetCounts}, using the provided
|
||||
* {@link ValueSource}. */
|
||||
/**
|
||||
* Create {@code RangeFacetCounts}, using the provided {@link ValueSource}.
|
||||
*
|
||||
* @deprecated Use {@link #DoubleRangeFacetCounts(String, DoubleValuesSource, FacetsCollector, DoubleRange...)}
|
||||
* */
|
||||
public DoubleRangeFacetCounts(String field, ValueSource valueSource, FacetsCollector hits, DoubleRange... ranges) throws IOException {
|
||||
this(field, valueSource, hits, null, ranges);
|
||||
}
|
||||
|
||||
/** Create {@code RangeFacetCounts}, using the provided
|
||||
* {@link ValueSource}, and using the provided Query as
|
||||
* a fastmatch: only documents passing the filter are
|
||||
* checked for the matching ranges. The filter must be
|
||||
* random access (implement {@link DocIdSet#bits}). */
|
||||
/**
|
||||
* Create {@code RangeFacetCounts} using the provided {@link DoubleValuesSource}
|
||||
*/
|
||||
public DoubleRangeFacetCounts(String field, DoubleValuesSource valueSource, FacetsCollector hits, DoubleRange... ranges) throws IOException {
|
||||
this(field, valueSource, hits, null, ranges);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create {@code RangeFacetCounts}, using the provided
|
||||
* {@link ValueSource}, and using the provided Query as
|
||||
* a fastmatch: only documents matching the query are
|
||||
* checked for the matching ranges.
|
||||
*
|
||||
* @deprecated Use ({@link #DoubleRangeFacetCounts(String, DoubleValuesSource, FacetsCollector, Query, DoubleRange...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public DoubleRangeFacetCounts(String field, ValueSource valueSource, FacetsCollector hits, Query fastMatchQuery, DoubleRange... ranges) throws IOException {
|
||||
this(field, valueSource.asDoubleValuesSource(), hits, fastMatchQuery, ranges);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create {@code RangeFacetCounts}, using the provided
|
||||
* {@link DoubleValuesSource}, and using the provided Query as
|
||||
* a fastmatch: only documents matching the query are
|
||||
* checked for the matching ranges.
|
||||
*/
|
||||
public DoubleRangeFacetCounts(String field, DoubleValuesSource valueSource, FacetsCollector hits, Query fastMatchQuery, DoubleRange... ranges) throws IOException {
|
||||
super(field, ranges, fastMatchQuery);
|
||||
count(valueSource, hits.getMatchingDocs());
|
||||
}
|
||||
|
||||
private void count(ValueSource valueSource, List<MatchingDocs> matchingDocs) throws IOException {
|
||||
private void count(DoubleValuesSource valueSource, List<MatchingDocs> matchingDocs) throws IOException {
|
||||
|
||||
DoubleRange[] ranges = (DoubleRange[]) this.ranges;
|
||||
|
||||
|
@ -96,7 +116,7 @@ public class DoubleRangeFacetCounts extends RangeFacetCounts {
|
|||
|
||||
int missingCount = 0;
|
||||
for (MatchingDocs hits : matchingDocs) {
|
||||
FunctionValues fv = valueSource.getValues(Collections.emptyMap(), hits.context);
|
||||
DoubleValues fv = valueSource.getValues(hits.context, null);
|
||||
|
||||
totCount += hits.totalHits;
|
||||
final DocIdSetIterator fastMatchDocs;
|
||||
|
@ -129,8 +149,8 @@ public class DoubleRangeFacetCounts extends RangeFacetCounts {
|
|||
}
|
||||
}
|
||||
// Skip missing docs:
|
||||
if (fv.exists(doc)) {
|
||||
counter.add(NumericUtils.doubleToSortableLong(fv.doubleVal(doc)));
|
||||
if (fv.advanceExact(doc)) {
|
||||
counter.add(NumericUtils.doubleToSortableLong(fv.doubleValue()));
|
||||
} else {
|
||||
missingCount++;
|
||||
}
|
||||
|
|
|
@ -17,17 +17,17 @@
|
|||
package org.apache.lucene.facet.range;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.search.ConstantScoreScorer;
|
||||
import org.apache.lucene.search.ConstantScoreWeight;
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.LongValues;
|
||||
import org.apache.lucene.search.LongValuesSource;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
import org.apache.lucene.search.TwoPhaseIterator;
|
||||
|
@ -87,9 +87,9 @@ public final class LongRange extends Range {
|
|||
private static class ValueSourceQuery extends Query {
|
||||
private final LongRange range;
|
||||
private final Query fastMatchQuery;
|
||||
private final ValueSource valueSource;
|
||||
private final LongValuesSource valueSource;
|
||||
|
||||
ValueSourceQuery(LongRange range, Query fastMatchQuery, ValueSource valueSource) {
|
||||
ValueSourceQuery(LongRange range, Query fastMatchQuery, LongValuesSource valueSource) {
|
||||
this.range = range;
|
||||
this.fastMatchQuery = fastMatchQuery;
|
||||
this.valueSource = valueSource;
|
||||
|
@ -150,11 +150,11 @@ public final class LongRange extends Range {
|
|||
approximation = s.iterator();
|
||||
}
|
||||
|
||||
final FunctionValues values = valueSource.getValues(Collections.emptyMap(), context);
|
||||
final LongValues values = valueSource.getValues(context, null);
|
||||
final TwoPhaseIterator twoPhase = new TwoPhaseIterator(approximation) {
|
||||
@Override
|
||||
public boolean matches() throws IOException {
|
||||
return range.accept(values.longVal(approximation.docID()));
|
||||
return values.advanceExact(approximation.docID()) && range.accept(values.longValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -169,8 +169,28 @@ public final class LongRange extends Range {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getQuery(Query, LongValuesSource)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Query getQuery(final Query fastMatchQuery, final ValueSource valueSource) {
|
||||
return new ValueSourceQuery(this, fastMatchQuery, valueSource.asLongValuesSource());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Query that matches documents in this range
|
||||
*
|
||||
* The query will check all documents that match the provided match query,
|
||||
* or every document in the index if the match query is null.
|
||||
*
|
||||
* If the value source is static, eg an indexed numeric field, it may be
|
||||
* faster to use {@link org.apache.lucene.search.PointRangeQuery}
|
||||
*
|
||||
* @param fastMatchQuery a query to use as a filter
|
||||
* @param valueSource the source of values for the range check
|
||||
*/
|
||||
public Query getQuery(Query fastMatchQuery, LongValuesSource valueSource) {
|
||||
return new ValueSourceQuery(this, fastMatchQuery, valueSource);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,27 +17,25 @@
|
|||
package org.apache.lucene.facet.range;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.facet.Facets;
|
||||
import org.apache.lucene.facet.FacetsCollector.MatchingDocs;
|
||||
import org.apache.lucene.facet.FacetsCollector;
|
||||
import org.apache.lucene.facet.FacetsCollector.MatchingDocs;
|
||||
import org.apache.lucene.index.IndexReaderContext;
|
||||
import org.apache.lucene.index.ReaderUtil;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.valuesource.LongFieldSource;
|
||||
import org.apache.lucene.search.DocIdSet;
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.LongValues;
|
||||
import org.apache.lucene.search.LongValuesSource;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
import org.apache.lucene.search.Weight;
|
||||
|
||||
/** {@link Facets} implementation that computes counts for
|
||||
* dynamic long ranges from a provided {@link ValueSource},
|
||||
* using {@link FunctionValues#longVal}. Use
|
||||
* dynamic long ranges from a provided {@link LongValuesSource}. Use
|
||||
* this for dimensions that change in real-time (e.g. a
|
||||
* relative time based dimension like "Past day", "Past 2
|
||||
* days", etc.) or that change for each request (e.g.
|
||||
|
@ -48,28 +46,49 @@ import org.apache.lucene.search.Weight;
|
|||
public class LongRangeFacetCounts extends RangeFacetCounts {
|
||||
|
||||
/** Create {@code LongRangeFacetCounts}, using {@link
|
||||
* LongFieldSource} from the specified field. */
|
||||
* LongValuesSource} from the specified field. */
|
||||
public LongRangeFacetCounts(String field, FacetsCollector hits, LongRange... ranges) throws IOException {
|
||||
this(field, new LongFieldSource(field), hits, ranges);
|
||||
this(field, LongValuesSource.fromLongField(field), hits, ranges);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create {@code RangeFacetCounts}, using the provided {@link ValueSource}.
|
||||
*
|
||||
* @deprecated Use {@link #LongRangeFacetCounts(String, LongValuesSource, FacetsCollector, LongRange...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public LongRangeFacetCounts(String field, ValueSource valueSource, FacetsCollector hits, LongRange... ranges) throws IOException {
|
||||
this(field, valueSource.asLongValuesSource(), hits, null, ranges);
|
||||
}
|
||||
|
||||
/** Create {@code RangeFacetCounts}, using the provided
|
||||
* {@link ValueSource}. */
|
||||
public LongRangeFacetCounts(String field, ValueSource valueSource, FacetsCollector hits, LongRange... ranges) throws IOException {
|
||||
public LongRangeFacetCounts(String field, LongValuesSource valueSource, FacetsCollector hits, LongRange... ranges) throws IOException {
|
||||
this(field, valueSource, hits, null, ranges);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create {@code RangeFacetCounts}, using the provided {@link ValueSource}.
|
||||
*
|
||||
* @deprecated Use {@link #LongRangeFacetCounts(String, LongValuesSource, FacetsCollector, Query, LongRange...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public LongRangeFacetCounts(String field, ValueSource valueSource, FacetsCollector hits, Query fastMatchQuery, LongRange... ranges) throws IOException {
|
||||
this(field, valueSource.asLongValuesSource(), hits, fastMatchQuery, ranges);
|
||||
}
|
||||
|
||||
|
||||
/** Create {@code RangeFacetCounts}, using the provided
|
||||
* {@link ValueSource}, and using the provided Filter as
|
||||
* a fastmatch: only documents passing the filter are
|
||||
* checked for the matching ranges. The filter must be
|
||||
* random access (implement {@link DocIdSet#bits}). */
|
||||
public LongRangeFacetCounts(String field, ValueSource valueSource, FacetsCollector hits, Query fastMatchQuery, LongRange... ranges) throws IOException {
|
||||
public LongRangeFacetCounts(String field, LongValuesSource valueSource, FacetsCollector hits, Query fastMatchQuery, LongRange... ranges) throws IOException {
|
||||
super(field, ranges, fastMatchQuery);
|
||||
count(valueSource, hits.getMatchingDocs());
|
||||
}
|
||||
|
||||
private void count(ValueSource valueSource, List<MatchingDocs> matchingDocs) throws IOException {
|
||||
private void count(LongValuesSource valueSource, List<MatchingDocs> matchingDocs) throws IOException {
|
||||
|
||||
LongRange[] ranges = (LongRange[]) this.ranges;
|
||||
|
||||
|
@ -77,7 +96,7 @@ public class LongRangeFacetCounts extends RangeFacetCounts {
|
|||
|
||||
int missingCount = 0;
|
||||
for (MatchingDocs hits : matchingDocs) {
|
||||
FunctionValues fv = valueSource.getValues(Collections.emptyMap(), hits.context);
|
||||
LongValues fv = valueSource.getValues(hits.context, null);
|
||||
|
||||
totCount += hits.totalHits;
|
||||
final DocIdSetIterator fastMatchDocs;
|
||||
|
@ -109,8 +128,8 @@ public class LongRangeFacetCounts extends RangeFacetCounts {
|
|||
}
|
||||
}
|
||||
// Skip missing docs:
|
||||
if (fv.exists(doc)) {
|
||||
counter.add(fv.longVal(doc));
|
||||
if (fv.advanceExact(doc)) {
|
||||
counter.add(fv.longValue());
|
||||
} else {
|
||||
missingCount++;
|
||||
}
|
||||
|
|
|
@ -16,10 +16,6 @@
|
|||
*/
|
||||
package org.apache.lucene.facet.range;
|
||||
|
||||
import org.apache.lucene.facet.DrillDownQuery; // javadocs
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.search.Query;
|
||||
|
||||
/** Base class for a single labeled range.
|
||||
*
|
||||
* @lucene.experimental */
|
||||
|
@ -36,33 +32,6 @@ public abstract class Range {
|
|||
this.label = label;
|
||||
}
|
||||
|
||||
/** Returns a new {@link Query} accepting only documents
|
||||
* in this range. This query might not be very efficient
|
||||
* when run on its own since it is optimized towards
|
||||
* random-access, so it is best used either with
|
||||
* {@link DrillDownQuery#add(String, Query) DrillDownQuery}
|
||||
* or when intersected with another query that can lead the
|
||||
* iteration. If the {@link ValueSource} is static, e.g. an
|
||||
* indexed numeric field, then it may be more efficient to use
|
||||
* {@link org.apache.lucene.search.PointRangeQuery}. The provided fastMatchQuery,
|
||||
* if non-null, will first be consulted, and only if
|
||||
* that is set for each document will the range then be
|
||||
* checked. */
|
||||
public abstract Query getQuery(Query fastMatchQuery, ValueSource valueSource);
|
||||
|
||||
/** Returns a new {@link Query} accepting only documents
|
||||
* in this range. This query might not be very efficient
|
||||
* when run on its own since it is optimized towards
|
||||
* random-access, so it is best used either with
|
||||
* {@link DrillDownQuery#add(String, Query) DrillDownQuery}
|
||||
* or when intersected with another query that can lead the
|
||||
* iteration. If the {@link ValueSource} is static, e.g. an
|
||||
* indexed numeric field, then it may be more efficient to
|
||||
* use {@link org.apache.lucene.search.PointRangeQuery}. */
|
||||
public Query getQuery(ValueSource valueSource) {
|
||||
return getQuery(null, valueSource);
|
||||
}
|
||||
|
||||
/** Invoke this for a useless range. */
|
||||
protected void failNoMatch() {
|
||||
throw new IllegalArgumentException("range \"" + label + "\" matches nothing");
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.lucene.facet.taxonomy;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
|
||||
class FakeScorer extends Scorer {
|
||||
|
||||
float score;
|
||||
int doc = -1;
|
||||
int freq = 1;
|
||||
|
||||
FakeScorer() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int docID() {
|
||||
return doc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocIdSetIterator iterator() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int freq() throws IOException {
|
||||
return freq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float score() throws IOException {
|
||||
return score;
|
||||
}
|
||||
}
|
|
@ -17,7 +17,6 @@
|
|||
package org.apache.lucene.facet.taxonomy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -29,6 +28,8 @@ import org.apache.lucene.queries.function.FunctionValues;
|
|||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
import org.apache.lucene.util.IntsRef;
|
||||
|
||||
|
@ -39,52 +40,94 @@ import org.apache.lucene.util.IntsRef;
|
|||
public class TaxonomyFacetSumValueSource extends FloatTaxonomyFacets {
|
||||
private final OrdinalsReader ordinalsReader;
|
||||
|
||||
/** Aggreggates float facet values from the provided
|
||||
/**
|
||||
* Aggreggates double facet values from the provided
|
||||
* {@link ValueSource}, pulling ordinals using {@link
|
||||
* DocValuesOrdinalsReader} against the default indexed
|
||||
* facet field {@link
|
||||
* FacetsConfig#DEFAULT_INDEX_FIELD_NAME}. */
|
||||
* FacetsConfig#DEFAULT_INDEX_FIELD_NAME}.
|
||||
*
|
||||
* @deprecated {@link #TaxonomyFacetSumValueSource(TaxonomyReader, FacetsConfig, FacetsCollector, DoubleValuesSource)}
|
||||
*/
|
||||
@Deprecated
|
||||
public TaxonomyFacetSumValueSource(TaxonomyReader taxoReader, FacetsConfig config,
|
||||
FacetsCollector fc, ValueSource valueSource) throws IOException {
|
||||
this(new DocValuesOrdinalsReader(FacetsConfig.DEFAULT_INDEX_FIELD_NAME), taxoReader, config, fc, valueSource);
|
||||
}
|
||||
|
||||
/** Aggreggates float facet values from the provided
|
||||
/**
|
||||
* Aggreggates double facet values from the provided
|
||||
* {@link DoubleValuesSource}, pulling ordinals using {@link
|
||||
* DocValuesOrdinalsReader} against the default indexed
|
||||
* facet field {@link FacetsConfig#DEFAULT_INDEX_FIELD_NAME}.
|
||||
*/
|
||||
public TaxonomyFacetSumValueSource(TaxonomyReader taxoReader, FacetsConfig config,
|
||||
FacetsCollector fc, DoubleValuesSource valueSource) throws IOException {
|
||||
this(new DocValuesOrdinalsReader(FacetsConfig.DEFAULT_INDEX_FIELD_NAME), taxoReader, config, fc, valueSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggreggates float facet values from the provided
|
||||
* {@link ValueSource}, and pulls ordinals from the
|
||||
* provided {@link OrdinalsReader}. */
|
||||
* provided {@link OrdinalsReader}.
|
||||
*
|
||||
* @deprecated use {@link #TaxonomyFacetSumValueSource(OrdinalsReader, TaxonomyReader, FacetsConfig, FacetsCollector, DoubleValuesSource)}
|
||||
*/
|
||||
@Deprecated
|
||||
public TaxonomyFacetSumValueSource(OrdinalsReader ordinalsReader, TaxonomyReader taxoReader,
|
||||
FacetsConfig config, FacetsCollector fc, ValueSource valueSource) throws IOException {
|
||||
super(ordinalsReader.getIndexFieldName(), taxoReader, config);
|
||||
this.ordinalsReader = ordinalsReader;
|
||||
sumValues(fc.getMatchingDocs(), fc.getKeepScores(), valueSource);
|
||||
sumValues(fc.getMatchingDocs(), fc.getKeepScores(), valueSource.asDoubleValuesSource());
|
||||
}
|
||||
|
||||
private final void sumValues(List<MatchingDocs> matchingDocs, boolean keepScores, ValueSource valueSource) throws IOException {
|
||||
final FakeScorer scorer = new FakeScorer();
|
||||
Map<String, Scorer> context = new HashMap<>();
|
||||
if (keepScores) {
|
||||
context.put("scorer", scorer);
|
||||
}
|
||||
/**
|
||||
* Aggreggates float facet values from the provided
|
||||
* {@link DoubleValuesSource}, and pulls ordinals from the
|
||||
* provided {@link OrdinalsReader}.
|
||||
*/
|
||||
public TaxonomyFacetSumValueSource(OrdinalsReader ordinalsReader, TaxonomyReader taxoReader,
|
||||
FacetsConfig config, FacetsCollector fc, DoubleValuesSource vs) throws IOException {
|
||||
super(ordinalsReader.getIndexFieldName(), taxoReader, config);
|
||||
this.ordinalsReader = ordinalsReader;
|
||||
sumValues(fc.getMatchingDocs(), fc.getKeepScores(), vs);
|
||||
}
|
||||
|
||||
private static DoubleValues scores(MatchingDocs hits) {
|
||||
return new DoubleValues() {
|
||||
|
||||
int index = -1;
|
||||
|
||||
@Override
|
||||
public double doubleValue() throws IOException {
|
||||
return hits.scores[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
index++;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void sumValues(List<MatchingDocs> matchingDocs, boolean keepScores, DoubleValuesSource valueSource) throws IOException {
|
||||
|
||||
IntsRef scratch = new IntsRef();
|
||||
for(MatchingDocs hits : matchingDocs) {
|
||||
OrdinalsReader.OrdinalsSegmentReader ords = ordinalsReader.getReader(hits.context);
|
||||
|
||||
int scoresIdx = 0;
|
||||
float[] scores = hits.scores;
|
||||
|
||||
FunctionValues functionValues = valueSource.getValues(context, hits.context);
|
||||
DoubleValues scores = keepScores ? scores(hits) : null;
|
||||
DoubleValues functionValues = valueSource.getValues(hits.context, scores);
|
||||
DocIdSetIterator docs = hits.bits.iterator();
|
||||
|
||||
int doc;
|
||||
while ((doc = docs.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
|
||||
ords.get(doc, scratch);
|
||||
if (keepScores) {
|
||||
scorer.doc = doc;
|
||||
scorer.score = scores[scoresIdx++];
|
||||
}
|
||||
float value = (float) functionValues.doubleVal(doc);
|
||||
for(int i=0;i<scratch.length;i++) {
|
||||
values[scratch.ints[i]] += value;
|
||||
if (functionValues.advanceExact(doc)) {
|
||||
float value = (float) functionValues.doubleValue();
|
||||
for (int i = 0; i < scratch.length; i++) {
|
||||
values[scratch.ints[i]] += value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,9 +135,13 @@ public class TaxonomyFacetSumValueSource extends FloatTaxonomyFacets {
|
|||
rollup();
|
||||
}
|
||||
|
||||
/** {@link ValueSource} that returns the score for each
|
||||
/**
|
||||
* {@link ValueSource} that returns the score for each
|
||||
* hit; use this to aggregate the sum of all hit scores
|
||||
* for each facet label. */
|
||||
* for each facet label.
|
||||
*
|
||||
* @deprecated Use {@link DoubleValuesSource#SCORES}
|
||||
*/
|
||||
public static class ScoreValueSource extends ValueSource {
|
||||
|
||||
/** Sole constructor. */
|
||||
|
|
|
@ -28,8 +28,8 @@ import org.apache.lucene.document.DoublePoint;
|
|||
import org.apache.lucene.document.LongPoint;
|
||||
import org.apache.lucene.document.NumericDocValuesField;
|
||||
import org.apache.lucene.facet.DrillDownQuery;
|
||||
import org.apache.lucene.facet.DrillSideways.DrillSidewaysResult;
|
||||
import org.apache.lucene.facet.DrillSideways;
|
||||
import org.apache.lucene.facet.DrillSideways.DrillSidewaysResult;
|
||||
import org.apache.lucene.facet.FacetField;
|
||||
import org.apache.lucene.facet.FacetResult;
|
||||
import org.apache.lucene.facet.FacetTestCase;
|
||||
|
@ -46,11 +46,11 @@ import org.apache.lucene.index.IndexWriterConfig;
|
|||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
|
||||
import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
|
||||
import org.apache.lucene.queries.function.valuesource.LongFieldSource;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.apache.lucene.search.Explanation;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
|
@ -708,7 +708,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
|
|||
|
||||
}
|
||||
|
||||
public void testCustomDoublesValueSource() throws Exception {
|
||||
public void testCustomDoubleValuesSource() throws Exception {
|
||||
Directory dir = newDirectory();
|
||||
RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
|
||||
|
||||
|
@ -720,33 +720,30 @@ public class TestRangeFacetCounts extends FacetTestCase {
|
|||
// Test wants 3 docs in one segment:
|
||||
writer.forceMerge(1);
|
||||
|
||||
final ValueSource vs = new ValueSource() {
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public FunctionValues getValues(Map ignored, LeafReaderContext ignored2) {
|
||||
return new DoubleDocValues(null) {
|
||||
@Override
|
||||
public double doubleVal(int doc) {
|
||||
return doc+1;
|
||||
}
|
||||
};
|
||||
}
|
||||
final DoubleValuesSource vs = new DoubleValuesSource() {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o != null && getClass() == o.getClass();
|
||||
}
|
||||
@Override
|
||||
public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException {
|
||||
return new DoubleValues() {
|
||||
int doc = -1;
|
||||
@Override
|
||||
public double doubleValue() throws IOException {
|
||||
return doc + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getClass().hashCode();
|
||||
}
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
this.doc = doc;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public boolean needsScores() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
FacetsConfig config = new FacetsConfig();
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.apache.lucene.queries.function.valuesource.IntFieldSource;
|
|||
import org.apache.lucene.queries.function.valuesource.LongFieldSource;
|
||||
import org.apache.lucene.search.BoostQuery;
|
||||
import org.apache.lucene.search.ConstantScoreQuery;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
|
@ -266,7 +267,7 @@ public class TestTaxonomyFacetSumValueSource extends FacetTestCase {
|
|||
|
||||
TopDocs td = FacetsCollector.search(newSearcher(r), csq, 10, fc);
|
||||
|
||||
Facets facets = new TaxonomyFacetSumValueSource(taxoReader, config, fc, new TaxonomyFacetSumValueSource.ScoreValueSource());
|
||||
Facets facets = new TaxonomyFacetSumValueSource(taxoReader, config, fc, DoubleValuesSource.SCORES);
|
||||
|
||||
int expected = (int) (td.getMaxScore() * td.totalHits);
|
||||
assertEquals(expected, facets.getSpecificValue("dim", "a").intValue());
|
||||
|
@ -408,7 +409,7 @@ public class TestTaxonomyFacetSumValueSource extends FacetTestCase {
|
|||
FacetsCollector.search(newSearcher(r), new MatchAllDocsQuery(), 10, fc);
|
||||
|
||||
Facets facets1 = getTaxonomyFacetCounts(taxoReader, config, fc);
|
||||
Facets facets2 = new TaxonomyFacetSumValueSource(new DocValuesOrdinalsReader("$b"), taxoReader, config, fc, new TaxonomyFacetSumValueSource.ScoreValueSource());
|
||||
Facets facets2 = new TaxonomyFacetSumValueSource(new DocValuesOrdinalsReader("$b"), taxoReader, config, fc, DoubleValuesSource.SCORES);
|
||||
|
||||
assertEquals(r.maxDoc(), facets1.getTopChildren(10, "a").value.intValue());
|
||||
assertEquals(r.maxDoc(), facets2.getTopChildren(10, "b").value.doubleValue(), 1E-10);
|
||||
|
|
|
@ -17,13 +17,20 @@
|
|||
package org.apache.lucene.queries.function;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.apache.lucene.search.FieldComparatorSource;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.LongValues;
|
||||
import org.apache.lucene.search.LongValuesSource;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
import org.apache.lucene.search.SimpleFieldComparator;
|
||||
import org.apache.lucene.search.SortField;
|
||||
|
||||
|
@ -78,6 +85,110 @@ public abstract class ValueSource {
|
|||
return context;
|
||||
}
|
||||
|
||||
private static class FakeScorer extends Scorer {
|
||||
|
||||
int current = -1;
|
||||
float score = 0;
|
||||
|
||||
FakeScorer() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int docID() {
|
||||
return current;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float score() throws IOException {
|
||||
return score;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int freq() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocIdSetIterator iterator() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose this ValueSource as a LongValuesSource
|
||||
*/
|
||||
public LongValuesSource asLongValuesSource() {
|
||||
return new LongValuesSource() {
|
||||
@Override
|
||||
public LongValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException {
|
||||
Map context = new IdentityHashMap<>();
|
||||
FakeScorer scorer = new FakeScorer();
|
||||
context.put("scorer", scorer);
|
||||
final FunctionValues fv = ValueSource.this.getValues(context, ctx);
|
||||
return new LongValues() {
|
||||
|
||||
@Override
|
||||
public long longValue() throws IOException {
|
||||
return fv.longVal(scorer.current);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
scorer.current = doc;
|
||||
if (scores != null && scores.advanceExact(doc))
|
||||
scorer.score = (float) scores.doubleValue();
|
||||
else
|
||||
scorer.score = 0;
|
||||
return fv.exists(doc);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsScores() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose this ValueSource as a DoubleValuesSource
|
||||
*/
|
||||
public DoubleValuesSource asDoubleValuesSource() {
|
||||
return new DoubleValuesSource() {
|
||||
@Override
|
||||
public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException {
|
||||
Map context = new HashMap<>();
|
||||
FakeScorer scorer = new FakeScorer();
|
||||
context.put("scorer", scorer);
|
||||
FunctionValues fv = ValueSource.this.getValues(context, ctx);
|
||||
return new DoubleValues() {
|
||||
|
||||
@Override
|
||||
public double doubleValue() throws IOException {
|
||||
return fv.doubleVal(scorer.current);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
scorer.current = doc;
|
||||
if (scores != null && scores.advanceExact(doc)) {
|
||||
scorer.score = (float) scores.doubleValue();
|
||||
}
|
||||
else
|
||||
scorer.score = 0;
|
||||
return fv.exists(doc);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsScores() {
|
||||
return true; // be on the safe side
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// Sorting by function
|
||||
|
|
Loading…
Reference in New Issue