mirror of https://github.com/apache/lucene.git
LUCENE-5339: add base class for taxo facet impls; catch wrong index field name for a given dim
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene5339@1543202 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f6cd7fda74
commit
5126543569
|
@ -71,6 +71,11 @@ public class CachedOrdinalsReader extends OrdinalsReader {
|
|||
return ords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIndexFieldName() {
|
||||
return source.getIndexFieldName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrdinalsSegmentReader getReader(AtomicReaderContext context) throws IOException {
|
||||
final CachedOrds cachedOrds = getCachedOrds(context);
|
||||
|
|
|
@ -31,7 +31,7 @@ public class DocValuesOrdinalsReader extends OrdinalsReader {
|
|||
private final String field;
|
||||
|
||||
public DocValuesOrdinalsReader() {
|
||||
this(FacetsConfig.DEFAULT_INDEXED_FIELD_NAME);
|
||||
this(FacetsConfig.DEFAULT_INDEX_FIELD_NAME);
|
||||
}
|
||||
|
||||
public DocValuesOrdinalsReader(String field) {
|
||||
|
@ -58,6 +58,11 @@ public class DocValuesOrdinalsReader extends OrdinalsReader {
|
|||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIndexFieldName() {
|
||||
return field;
|
||||
}
|
||||
|
||||
/** Subclass & override if you change the encoding. */
|
||||
protected void decode(BytesRef buf, IntsRef ordinals) {
|
||||
|
||||
|
|
|
@ -45,12 +45,12 @@ import org.apache.lucene.util.IntsRef;
|
|||
public class FacetIndexWriter extends IndexWriter {
|
||||
|
||||
private final TaxonomyWriter taxoWriter;
|
||||
private final FacetsConfig facetsConfig;
|
||||
private final FacetsConfig config;
|
||||
|
||||
public FacetIndexWriter(Directory d, IndexWriterConfig conf, TaxonomyWriter taxoWriter, FacetsConfig facetsConfig) throws IOException {
|
||||
public FacetIndexWriter(Directory d, IndexWriterConfig conf, TaxonomyWriter taxoWriter, FacetsConfig config) throws IOException {
|
||||
super(d, conf);
|
||||
this.taxoWriter = taxoWriter;
|
||||
this.facetsConfig = facetsConfig;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
// nocommit maybe we could somehow "own" TaxonomyWriter
|
||||
|
@ -73,38 +73,38 @@ public class FacetIndexWriter extends IndexWriter {
|
|||
for(IndexableField field : doc.indexableFields()) {
|
||||
if (field.fieldType() == FacetField.TYPE) {
|
||||
FacetField facetField = (FacetField) field;
|
||||
FacetsConfig.DimConfig dimConfig = facetsConfig.getDimConfig(field.name());
|
||||
String indexedFieldName = dimConfig.indexedFieldName;
|
||||
List<FacetField> fields = byField.get(indexedFieldName);
|
||||
FacetsConfig.DimConfig dimConfig = config.getDimConfig(facetField.dim);
|
||||
String indexFieldName = dimConfig.indexFieldName;
|
||||
List<FacetField> fields = byField.get(indexFieldName);
|
||||
if (fields == null) {
|
||||
fields = new ArrayList<FacetField>();
|
||||
byField.put(indexedFieldName, fields);
|
||||
byField.put(indexFieldName, fields);
|
||||
}
|
||||
fields.add(facetField);
|
||||
}
|
||||
|
||||
if (field.fieldType() == SortedSetDocValuesFacetField.TYPE) {
|
||||
SortedSetDocValuesFacetField facetField = (SortedSetDocValuesFacetField) field;
|
||||
FacetsConfig.DimConfig dimConfig = facetsConfig.getDimConfig(field.name());
|
||||
String indexedFieldName = dimConfig.indexedFieldName;
|
||||
List<SortedSetDocValuesFacetField> fields = dvByField.get(indexedFieldName);
|
||||
FacetsConfig.DimConfig dimConfig = config.getDimConfig(facetField.dim);
|
||||
String indexFieldName = dimConfig.indexFieldName;
|
||||
List<SortedSetDocValuesFacetField> fields = dvByField.get(indexFieldName);
|
||||
if (fields == null) {
|
||||
fields = new ArrayList<SortedSetDocValuesFacetField>();
|
||||
dvByField.put(indexedFieldName, fields);
|
||||
dvByField.put(indexFieldName, fields);
|
||||
}
|
||||
fields.add(facetField);
|
||||
}
|
||||
|
||||
if (field.fieldType() == AssociationFacetField.TYPE) {
|
||||
AssociationFacetField facetField = (AssociationFacetField) field;
|
||||
FacetsConfig.DimConfig dimConfig = facetsConfig.getDimConfig(field.name());
|
||||
FacetsConfig.DimConfig dimConfig = config.getDimConfig(facetField.dim);
|
||||
|
||||
// nocommit how to use a different default name for assocs?
|
||||
String indexedFieldName = dimConfig.indexedFieldName;
|
||||
List<AssociationFacetField> fields = assocByField.get(indexedFieldName);
|
||||
String indexFieldName = dimConfig.indexFieldName;
|
||||
List<AssociationFacetField> fields = assocByField.get(indexFieldName);
|
||||
if (fields == null) {
|
||||
fields = new ArrayList<AssociationFacetField>();
|
||||
assocByField.put(indexedFieldName, fields);
|
||||
assocByField.put(indexFieldName, fields);
|
||||
}
|
||||
fields.add(facetField);
|
||||
}
|
||||
|
@ -157,13 +157,13 @@ public class FacetIndexWriter extends IndexWriter {
|
|||
// nocommit maybe we can somehow catch singleValued
|
||||
// dim appearing more than once?
|
||||
|
||||
String indexedFieldName = ent.getKey();
|
||||
String indexFieldName = ent.getKey();
|
||||
//System.out.println(" fields=" + ent.getValue());
|
||||
|
||||
IntsRef ordinals = new IntsRef(32);
|
||||
for(FacetField facetField : ent.getValue()) {
|
||||
|
||||
FacetsConfig.DimConfig ft = facetsConfig.getDimConfig(facetField.dim);
|
||||
FacetsConfig.DimConfig ft = config.getDimConfig(facetField.dim);
|
||||
if (facetField.path.length > 1 && ft.hierarchical == false) {
|
||||
throw new IllegalArgumentException("dimension \"" + facetField.dim + "\" is not hierarchical yet has " + facetField.path.length + " components");
|
||||
}
|
||||
|
@ -188,13 +188,13 @@ public class FacetIndexWriter extends IndexWriter {
|
|||
|
||||
// Drill down:
|
||||
for(int i=2;i<=cp.length;i++) {
|
||||
addedIndexedFields.add(new StringField(indexedFieldName, pathToString(cp.components, i), Field.Store.NO));
|
||||
addedIndexedFields.add(new StringField(indexFieldName, pathToString(cp.components, i), Field.Store.NO));
|
||||
}
|
||||
}
|
||||
|
||||
// Facet counts:
|
||||
// DocValues are considered stored fields:
|
||||
addedStoredFields.add(new BinaryDocValuesField(indexedFieldName, dedupAndEncode(ordinals)));
|
||||
addedStoredFields.add(new BinaryDocValuesField(indexFieldName, dedupAndEncode(ordinals)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,8 +202,8 @@ public class FacetIndexWriter extends IndexWriter {
|
|||
//System.out.println("process SSDV: " + byField);
|
||||
for(Map.Entry<String,List<SortedSetDocValuesFacetField>> ent : byField.entrySet()) {
|
||||
|
||||
String indexedFieldName = ent.getKey();
|
||||
//System.out.println(" field=" + indexedFieldName);
|
||||
String indexFieldName = ent.getKey();
|
||||
//System.out.println(" field=" + indexFieldName);
|
||||
|
||||
for(SortedSetDocValuesFacetField facetField : ent.getValue()) {
|
||||
FacetLabel cp = new FacetLabel(facetField.dim, facetField.label);
|
||||
|
@ -211,10 +211,10 @@ public class FacetIndexWriter extends IndexWriter {
|
|||
//System.out.println("add " + fullPath);
|
||||
|
||||
// For facet counts:
|
||||
addedStoredFields.add(new SortedSetDocValuesField(indexedFieldName, new BytesRef(fullPath)));
|
||||
addedStoredFields.add(new SortedSetDocValuesField(indexFieldName, new BytesRef(fullPath)));
|
||||
|
||||
// For drill-down:
|
||||
addedIndexedFields.add(new StringField(indexedFieldName, fullPath, Field.Store.NO));
|
||||
addedIndexedFields.add(new StringField(indexFieldName, fullPath, Field.Store.NO));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ public class FacetIndexWriter extends IndexWriter {
|
|||
for(Map.Entry<String,List<AssociationFacetField>> ent : byField.entrySet()) {
|
||||
byte[] bytes = new byte[16];
|
||||
int upto = 0;
|
||||
String indexedFieldName = ent.getKey();
|
||||
String indexFieldName = ent.getKey();
|
||||
for(AssociationFacetField field : ent.getValue()) {
|
||||
// NOTE: we don't add parents for associations
|
||||
// nocommit is that right? maybe we are supposed to
|
||||
|
@ -244,7 +244,7 @@ public class FacetIndexWriter extends IndexWriter {
|
|||
System.arraycopy(field.assoc.bytes, field.assoc.offset, bytes, upto, field.assoc.length);
|
||||
upto += field.assoc.length;
|
||||
}
|
||||
addedStoredFields.add(new BinaryDocValuesField(indexedFieldName, new BytesRef(bytes, 0, upto)));
|
||||
addedStoredFields.add(new BinaryDocValuesField(indexFieldName, new BytesRef(bytes, 0, upto)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
* the setters in this class to change that for any dims */
|
||||
public class FacetsConfig {
|
||||
|
||||
public static final String DEFAULT_INDEXED_FIELD_NAME = "$facets";
|
||||
public static final String DEFAULT_INDEX_FIELD_NAME = "$facets";
|
||||
|
||||
// nocommit pull DimType into here (shai?)
|
||||
|
||||
|
@ -38,7 +38,7 @@ public class FacetsConfig {
|
|||
|
||||
/** Actual field where this dimension's facet labels
|
||||
* should be indexed */
|
||||
String indexedFieldName = DEFAULT_INDEXED_FIELD_NAME;
|
||||
String indexFieldName = DEFAULT_INDEX_FIELD_NAME;
|
||||
}
|
||||
|
||||
public final static DimConfig DEFAULT_DIM_CONFIG = new DimConfig();
|
||||
|
@ -70,13 +70,13 @@ public class FacetsConfig {
|
|||
ft.multiValued = true;
|
||||
}
|
||||
|
||||
public synchronized void setIndexedFieldName(String dimName, String indexedFieldName) {
|
||||
public synchronized void setIndexFieldName(String dimName, String indexFieldName) {
|
||||
DimConfig ft = fieldTypes.get(dimName);
|
||||
if (ft == null) {
|
||||
ft = new DimConfig();
|
||||
fieldTypes.put(dimName, ft);
|
||||
}
|
||||
ft.indexedFieldName = indexedFieldName;
|
||||
ft.indexFieldName = indexFieldName;
|
||||
}
|
||||
|
||||
Map<String,DimConfig> getDimConfigs() {
|
||||
|
|
|
@ -33,35 +33,22 @@ import org.apache.lucene.util.BytesRef;
|
|||
import org.apache.lucene.util.FixedBitSet;
|
||||
|
||||
// nocommit jdoc that this assumes/requires the default encoding
|
||||
public class FastTaxonomyFacetCounts extends Facets {
|
||||
private final FacetsConfig facetsConfig;
|
||||
private final TaxonomyReader taxoReader;
|
||||
public class FastTaxonomyFacetCounts extends TaxonomyFacets {
|
||||
private final int[] counts;
|
||||
private final String facetsFieldName;
|
||||
private final int[] children;
|
||||
private final int[] parents;
|
||||
private final int[] siblings;
|
||||
|
||||
public FastTaxonomyFacetCounts(TaxonomyReader taxoReader, FacetsConfig facetsConfig, SimpleFacetsCollector fc) throws IOException {
|
||||
this(FacetsConfig.DEFAULT_INDEXED_FIELD_NAME, taxoReader, facetsConfig, fc);
|
||||
public FastTaxonomyFacetCounts(TaxonomyReader taxoReader, FacetsConfig config, SimpleFacetsCollector fc) throws IOException {
|
||||
this(FacetsConfig.DEFAULT_INDEX_FIELD_NAME, taxoReader, config, fc);
|
||||
}
|
||||
|
||||
public FastTaxonomyFacetCounts(String facetsFieldName, TaxonomyReader taxoReader, FacetsConfig facetsConfig, SimpleFacetsCollector fc) throws IOException {
|
||||
this.taxoReader = taxoReader;
|
||||
this.facetsFieldName = facetsFieldName;
|
||||
this.facetsConfig = facetsConfig;
|
||||
ParallelTaxonomyArrays pta = taxoReader.getParallelTaxonomyArrays();
|
||||
children = pta.children();
|
||||
parents = pta.parents();
|
||||
siblings = pta.siblings();
|
||||
public FastTaxonomyFacetCounts(String indexFieldName, TaxonomyReader taxoReader, FacetsConfig config, SimpleFacetsCollector fc) throws IOException {
|
||||
super(indexFieldName, taxoReader, config);
|
||||
counts = new int[taxoReader.getSize()];
|
||||
count(fc.getMatchingDocs());
|
||||
}
|
||||
|
||||
private final void count(List<MatchingDocs> matchingDocs) throws IOException {
|
||||
//System.out.println("count matchingDocs=" + matchingDocs + " facetsField=" + facetsFieldName);
|
||||
for(MatchingDocs hits : matchingDocs) {
|
||||
BinaryDocValues dv = hits.context.reader().getBinaryDocValues(facetsFieldName);
|
||||
BinaryDocValues dv = hits.context.reader().getBinaryDocValues(indexFieldName);
|
||||
if (dv == null) { // this reader does not have DocValues for the requested category list
|
||||
continue;
|
||||
}
|
||||
|
@ -97,13 +84,13 @@ public class FastTaxonomyFacetCounts extends Facets {
|
|||
// nocommit we could do this lazily instead:
|
||||
|
||||
// Rollup any necessary dims:
|
||||
for(Map.Entry<String,FacetsConfig.DimConfig> ent : facetsConfig.getDimConfigs().entrySet()) {
|
||||
for(Map.Entry<String,FacetsConfig.DimConfig> ent : config.getDimConfigs().entrySet()) {
|
||||
String dim = ent.getKey();
|
||||
FacetsConfig.DimConfig ft = ent.getValue();
|
||||
if (ft.hierarchical && ft.multiValued == false) {
|
||||
int dimRootOrd = taxoReader.getOrdinal(new FacetLabel(dim));
|
||||
// It can be -1 if this field was declared in the
|
||||
// facetsConfig but never indexed:
|
||||
// config but never indexed:
|
||||
if (dimRootOrd > 0) {
|
||||
counts[dimRootOrd] += rollup(children[dimRootOrd]);
|
||||
}
|
||||
|
@ -126,6 +113,7 @@ public class FastTaxonomyFacetCounts extends Facets {
|
|||
* this path doesn't exist, else the count. */
|
||||
@Override
|
||||
public Number getSpecificValue(String dim, String... path) throws IOException {
|
||||
verifyDim(dim);
|
||||
int ord = taxoReader.getOrdinal(FacetLabel.create(dim, path));
|
||||
if (ord < 0) {
|
||||
return -1;
|
||||
|
@ -135,16 +123,14 @@ public class FastTaxonomyFacetCounts extends Facets {
|
|||
|
||||
@Override
|
||||
public SimpleFacetResult getTopChildren(int topN, String dim, String... path) throws IOException {
|
||||
FacetsConfig.DimConfig dimConfig = verifyDim(dim);
|
||||
|
||||
FacetLabel cp = FacetLabel.create(dim, path);
|
||||
int ord = taxoReader.getOrdinal(cp);
|
||||
if (ord == -1) {
|
||||
int dimOrd = taxoReader.getOrdinal(cp);
|
||||
if (dimOrd == -1) {
|
||||
//System.out.println("no ord for path=" + path);
|
||||
return null;
|
||||
}
|
||||
return getTopChildren(cp, ord, topN);
|
||||
}
|
||||
|
||||
private SimpleFacetResult getTopChildren(FacetLabel path, int dimOrd, int topN) throws IOException {
|
||||
|
||||
TopOrdAndIntQueue q = new TopOrdAndIntQueue(topN);
|
||||
|
||||
|
@ -174,14 +160,10 @@ public class FastTaxonomyFacetCounts extends Facets {
|
|||
}
|
||||
|
||||
if (totCount == 0) {
|
||||
//System.out.println("totCount=0 for path=" + path);
|
||||
return null;
|
||||
}
|
||||
|
||||
FacetsConfig.DimConfig ft = facetsConfig.getDimConfig(path.components[0]);
|
||||
// nocommit shouldn't we verify the indexedFieldName
|
||||
// matches what was passed to our ctor?
|
||||
if (ft.hierarchical && ft.multiValued) {
|
||||
if (dimConfig.hierarchical && dimConfig.multiValued) {
|
||||
totCount = counts[dimOrd];
|
||||
}
|
||||
|
||||
|
@ -189,40 +171,9 @@ public class FastTaxonomyFacetCounts extends Facets {
|
|||
for(int i=labelValues.length-1;i>=0;i--) {
|
||||
TopOrdAndIntQueue.OrdAndValue ordAndValue = q.pop();
|
||||
FacetLabel child = taxoReader.getPath(ordAndValue.ord);
|
||||
labelValues[i] = new LabelAndValue(child.components[path.length], ordAndValue.value);
|
||||
labelValues[i] = new LabelAndValue(child.components[cp.length], ordAndValue.value);
|
||||
}
|
||||
|
||||
return new SimpleFacetResult(path, totCount, labelValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SimpleFacetResult> getAllDims(int topN) throws IOException {
|
||||
int ord = children[TaxonomyReader.ROOT_ORDINAL];
|
||||
List<SimpleFacetResult> results = new ArrayList<SimpleFacetResult>();
|
||||
while (ord != TaxonomyReader.INVALID_ORDINAL) {
|
||||
SimpleFacetResult result = getTopChildren(taxoReader.getPath(ord), ord, topN);
|
||||
if (result != null) {
|
||||
results.add(result);
|
||||
}
|
||||
ord = siblings[ord];
|
||||
}
|
||||
|
||||
// Sort by highest count:
|
||||
Collections.sort(results,
|
||||
new Comparator<SimpleFacetResult>() {
|
||||
@Override
|
||||
public int compare(SimpleFacetResult a, SimpleFacetResult b) {
|
||||
if (a.value.intValue() > b.value.intValue()) {
|
||||
return -1;
|
||||
} else if (b.value.intValue() > a.value.intValue()) {
|
||||
return 1;
|
||||
} else {
|
||||
// Tie break by dimension
|
||||
return a.path.components[0].compareTo(b.path.components[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
return new SimpleFacetResult(cp, totCount, labelValues);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,4 +34,6 @@ public abstract class OrdinalsReader {
|
|||
|
||||
/** Set current atomic reader. */
|
||||
public abstract OrdinalsSegmentReader getReader(AtomicReaderContext context) throws IOException;
|
||||
|
||||
public abstract String getIndexFieldName();
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ public final class SimpleDrillDownQuery extends Query {
|
|||
// merge a facet label in:
|
||||
throw new RuntimeException("cannot merge with custom Query");
|
||||
}
|
||||
String indexedField = config.getDimConfig(dim).indexedFieldName;
|
||||
String indexedField = config.getDimConfig(dim).indexFieldName;
|
||||
|
||||
BooleanQuery bq = (BooleanQuery) q.getQuery();
|
||||
bq.add(new TermQuery(term(indexedField, dim, path)), Occur.SHOULD);
|
||||
|
@ -150,7 +150,7 @@ public final class SimpleDrillDownQuery extends Query {
|
|||
merge(dim, path);
|
||||
return;
|
||||
}
|
||||
String indexedField = config.getDimConfig(dim).indexedFieldName;
|
||||
String indexedField = config.getDimConfig(dim).indexFieldName;
|
||||
|
||||
BooleanQuery bq = new BooleanQuery(true); // disable coord
|
||||
if (path.length == 0) {
|
||||
|
|
|
@ -74,7 +74,7 @@ public final class SortedSetDocValuesReaderState {
|
|||
private final Map<String,OrdRange> prefixToOrdRange = new HashMap<String,OrdRange>();
|
||||
|
||||
public SortedSetDocValuesReaderState(IndexReader reader) throws IOException {
|
||||
this(reader, FacetsConfig.DEFAULT_INDEXED_FIELD_NAME);
|
||||
this(reader, FacetsConfig.DEFAULT_INDEX_FIELD_NAME);
|
||||
}
|
||||
|
||||
/** Create an instance, scanning the {@link
|
||||
|
|
|
@ -32,28 +32,17 @@ import org.apache.lucene.index.BinaryDocValues;
|
|||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
|
||||
// nocommit rename to TaxonomySumFloatAssociationFacets
|
||||
// nocommit jdoc that this assumes/requires the default encoding
|
||||
public class SumFloatAssociationFacets extends Facets {
|
||||
private final FacetsConfig facetsConfig;
|
||||
private final TaxonomyReader taxoReader;
|
||||
public class SumFloatAssociationFacets extends TaxonomyFacets {
|
||||
private final float[] values;
|
||||
private final String facetsFieldName;
|
||||
private final int[] children;
|
||||
private final int[] parents;
|
||||
private final int[] siblings;
|
||||
|
||||
public SumFloatAssociationFacets(TaxonomyReader taxoReader, FacetsConfig facetsConfig, SimpleFacetsCollector fc) throws IOException {
|
||||
this(FacetsConfig.DEFAULT_INDEXED_FIELD_NAME, taxoReader, facetsConfig, fc);
|
||||
public SumFloatAssociationFacets(TaxonomyReader taxoReader, FacetsConfig config, SimpleFacetsCollector fc) throws IOException {
|
||||
this(FacetsConfig.DEFAULT_INDEX_FIELD_NAME, taxoReader, config, fc);
|
||||
}
|
||||
|
||||
public SumFloatAssociationFacets(String facetsFieldName, TaxonomyReader taxoReader, FacetsConfig facetsConfig, SimpleFacetsCollector fc) throws IOException {
|
||||
this.facetsFieldName = facetsFieldName;
|
||||
this.taxoReader = taxoReader;
|
||||
this.facetsConfig = facetsConfig;
|
||||
ParallelTaxonomyArrays pta = taxoReader.getParallelTaxonomyArrays();
|
||||
children = pta.children();
|
||||
parents = pta.parents();
|
||||
siblings = pta.siblings();
|
||||
public SumFloatAssociationFacets(String indexFieldName, TaxonomyReader taxoReader, FacetsConfig config, SimpleFacetsCollector fc) throws IOException {
|
||||
super(indexFieldName, taxoReader, config);
|
||||
values = new float[taxoReader.getSize()];
|
||||
sumValues(fc.getMatchingDocs());
|
||||
}
|
||||
|
@ -61,7 +50,7 @@ public class SumFloatAssociationFacets extends Facets {
|
|||
private final void sumValues(List<MatchingDocs> matchingDocs) throws IOException {
|
||||
//System.out.println("count matchingDocs=" + matchingDocs + " facetsField=" + facetsFieldName);
|
||||
for(MatchingDocs hits : matchingDocs) {
|
||||
BinaryDocValues dv = hits.context.reader().getBinaryDocValues(facetsFieldName);
|
||||
BinaryDocValues dv = hits.context.reader().getBinaryDocValues(indexFieldName);
|
||||
if (dv == null) { // this reader does not have DocValues for the requested category list
|
||||
continue;
|
||||
}
|
||||
|
@ -101,13 +90,13 @@ public class SumFloatAssociationFacets extends Facets {
|
|||
// Rollup any necessary dims:
|
||||
// nocommit should we rollup?
|
||||
/*
|
||||
for(Map.Entry<String,FacetsConfig.DimConfig> ent : facetsConfig.getDimConfigs().entrySet()) {
|
||||
for(Map.Entry<String,FacetsConfig.DimConfig> ent : config.getDimConfigs().entrySet()) {
|
||||
String dim = ent.getKey();
|
||||
FacetsConfig.DimConfig ft = ent.getValue();
|
||||
if (ft.hierarchical && ft.multiValued == false) {
|
||||
int dimRootOrd = taxoReader.getOrdinal(new FacetLabel(dim));
|
||||
// It can be -1 if this field was declared in the
|
||||
// facetsConfig but never indexed:
|
||||
// config but never indexed:
|
||||
if (dimRootOrd > 0) {
|
||||
counts[dimRootOrd] += rollup(children[dimRootOrd]);
|
||||
}
|
||||
|
@ -131,6 +120,7 @@ public class SumFloatAssociationFacets extends Facets {
|
|||
* this path doesn't exist, else the count. */
|
||||
@Override
|
||||
public Number getSpecificValue(String dim, String... path) throws IOException {
|
||||
verifyDim(dim);
|
||||
int ord = taxoReader.getOrdinal(FacetLabel.create(dim, path));
|
||||
if (ord < 0) {
|
||||
return -1;
|
||||
|
@ -140,16 +130,13 @@ public class SumFloatAssociationFacets extends Facets {
|
|||
|
||||
@Override
|
||||
public SimpleFacetResult getTopChildren(int topN, String dim, String... path) throws IOException {
|
||||
FacetsConfig.DimConfig dimConfig = verifyDim(dim);
|
||||
FacetLabel cp = FacetLabel.create(dim, path);
|
||||
int ord = taxoReader.getOrdinal(cp);
|
||||
if (ord == -1) {
|
||||
int dimOrd = taxoReader.getOrdinal(cp);
|
||||
if (dimOrd == -1) {
|
||||
//System.out.println("no ord for path=" + path);
|
||||
return null;
|
||||
}
|
||||
return getTopChildren(cp, ord, topN);
|
||||
}
|
||||
|
||||
private SimpleFacetResult getTopChildren(FacetLabel path, int dimOrd, int topN) throws IOException {
|
||||
|
||||
TopOrdAndFloatQueue q = new TopOrdAndFloatQueue(topN);
|
||||
|
||||
|
@ -184,10 +171,7 @@ public class SumFloatAssociationFacets extends Facets {
|
|||
}
|
||||
|
||||
/*
|
||||
FacetsConfig.DimConfig ft = facetsConfig.getDimConfig(path.components[0]);
|
||||
// nocommit shouldn't we verify the indexedFieldName
|
||||
// matches what was passed to our ctor?
|
||||
if (ft.hierarchical && ft.multiValued) {
|
||||
if (dimConfig.hierarchical && dimConfig.multiValued) {
|
||||
totCount = counts[dimOrd];
|
||||
}
|
||||
*/
|
||||
|
@ -199,37 +183,6 @@ public class SumFloatAssociationFacets extends Facets {
|
|||
labelValues[i] = new LabelAndValue(child.components[path.length], ordAndValue.value);
|
||||
}
|
||||
|
||||
return new SimpleFacetResult(path, sumValue, labelValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SimpleFacetResult> getAllDims(int topN) throws IOException {
|
||||
int ord = children[TaxonomyReader.ROOT_ORDINAL];
|
||||
List<SimpleFacetResult> results = new ArrayList<SimpleFacetResult>();
|
||||
while (ord != TaxonomyReader.INVALID_ORDINAL) {
|
||||
SimpleFacetResult result = getTopChildren(taxoReader.getPath(ord), ord, topN);
|
||||
if (result != null) {
|
||||
results.add(result);
|
||||
}
|
||||
ord = siblings[ord];
|
||||
}
|
||||
|
||||
// Sort by highest count:
|
||||
Collections.sort(results,
|
||||
new Comparator<SimpleFacetResult>() {
|
||||
@Override
|
||||
public int compare(SimpleFacetResult a, SimpleFacetResult b) {
|
||||
if (a.value.intValue() > b.value.intValue()) {
|
||||
return -1;
|
||||
} else if (b.value.intValue() > a.value.intValue()) {
|
||||
return 1;
|
||||
} else {
|
||||
// Tie break by dimension
|
||||
return a.path.components[0].compareTo(b.path.components[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
return new SimpleFacetResult(cp, sumValue, labelValues);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,28 +32,17 @@ import org.apache.lucene.index.BinaryDocValues;
|
|||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
|
||||
// nocommit rename to TaxonomySumIntAssociationFacets
|
||||
// nocommit jdoc that this assumes/requires the default encoding
|
||||
public class SumIntAssociationFacets extends Facets {
|
||||
private final FacetsConfig facetsConfig;
|
||||
private final TaxonomyReader taxoReader;
|
||||
public class SumIntAssociationFacets extends TaxonomyFacets {
|
||||
private final int[] values;
|
||||
private final String facetsFieldName;
|
||||
private final int[] children;
|
||||
private final int[] parents;
|
||||
private final int[] siblings;
|
||||
|
||||
public SumIntAssociationFacets(TaxonomyReader taxoReader, FacetsConfig facetsConfig, SimpleFacetsCollector fc) throws IOException {
|
||||
this(FacetsConfig.DEFAULT_INDEXED_FIELD_NAME, taxoReader, facetsConfig, fc);
|
||||
public SumIntAssociationFacets(TaxonomyReader taxoReader, FacetsConfig config, SimpleFacetsCollector fc) throws IOException {
|
||||
this(FacetsConfig.DEFAULT_INDEX_FIELD_NAME, taxoReader, config, fc);
|
||||
}
|
||||
|
||||
public SumIntAssociationFacets(String facetsFieldName, TaxonomyReader taxoReader, FacetsConfig facetsConfig, SimpleFacetsCollector fc) throws IOException {
|
||||
this.facetsFieldName = facetsFieldName;
|
||||
this.taxoReader = taxoReader;
|
||||
this.facetsConfig = facetsConfig;
|
||||
ParallelTaxonomyArrays pta = taxoReader.getParallelTaxonomyArrays();
|
||||
children = pta.children();
|
||||
parents = pta.parents();
|
||||
siblings = pta.siblings();
|
||||
public SumIntAssociationFacets(String indexFieldName, TaxonomyReader taxoReader, FacetsConfig config, SimpleFacetsCollector fc) throws IOException {
|
||||
super(indexFieldName, taxoReader, config);
|
||||
values = new int[taxoReader.getSize()];
|
||||
sumValues(fc.getMatchingDocs());
|
||||
}
|
||||
|
@ -61,7 +50,7 @@ public class SumIntAssociationFacets extends Facets {
|
|||
private final void sumValues(List<MatchingDocs> matchingDocs) throws IOException {
|
||||
//System.out.println("count matchingDocs=" + matchingDocs + " facetsField=" + facetsFieldName);
|
||||
for(MatchingDocs hits : matchingDocs) {
|
||||
BinaryDocValues dv = hits.context.reader().getBinaryDocValues(facetsFieldName);
|
||||
BinaryDocValues dv = hits.context.reader().getBinaryDocValues(indexFieldName);
|
||||
if (dv == null) { // this reader does not have DocValues for the requested category list
|
||||
continue;
|
||||
}
|
||||
|
@ -101,13 +90,13 @@ public class SumIntAssociationFacets extends Facets {
|
|||
// Rollup any necessary dims:
|
||||
// nocommit should we rollup?
|
||||
/*
|
||||
for(Map.Entry<String,FacetsConfig.DimConfig> ent : facetsConfig.getDimConfigs().entrySet()) {
|
||||
for(Map.Entry<String,FacetsConfig.DimConfig> ent : config.getDimConfigs().entrySet()) {
|
||||
String dim = ent.getKey();
|
||||
FacetsConfig.DimConfig ft = ent.getValue();
|
||||
if (ft.hierarchical && ft.multiValued == false) {
|
||||
int dimRootOrd = taxoReader.getOrdinal(new FacetLabel(dim));
|
||||
// It can be -1 if this field was declared in the
|
||||
// facetsConfig but never indexed:
|
||||
// config but never indexed:
|
||||
if (dimRootOrd > 0) {
|
||||
counts[dimRootOrd] += rollup(children[dimRootOrd]);
|
||||
}
|
||||
|
@ -131,6 +120,7 @@ public class SumIntAssociationFacets extends Facets {
|
|||
* this path doesn't exist, else the count. */
|
||||
@Override
|
||||
public Number getSpecificValue(String dim, String... path) throws IOException {
|
||||
verifyDim(dim);
|
||||
int ord = taxoReader.getOrdinal(FacetLabel.create(dim, path));
|
||||
if (ord < 0) {
|
||||
return -1;
|
||||
|
@ -140,16 +130,13 @@ public class SumIntAssociationFacets extends Facets {
|
|||
|
||||
@Override
|
||||
public SimpleFacetResult getTopChildren(int topN, String dim, String... path) throws IOException {
|
||||
verifyDim(dim);
|
||||
FacetLabel cp = FacetLabel.create(dim, path);
|
||||
int ord = taxoReader.getOrdinal(cp);
|
||||
if (ord == -1) {
|
||||
int dimOrd = taxoReader.getOrdinal(cp);
|
||||
if (dimOrd == -1) {
|
||||
//System.out.println("no ord for path=" + path);
|
||||
return null;
|
||||
}
|
||||
return getTopChildren(cp, ord, topN);
|
||||
}
|
||||
|
||||
private SimpleFacetResult getTopChildren(FacetLabel path, int dimOrd, int topN) throws IOException {
|
||||
|
||||
TopOrdAndIntQueue q = new TopOrdAndIntQueue(topN);
|
||||
|
||||
|
@ -184,9 +171,7 @@ public class SumIntAssociationFacets extends Facets {
|
|||
}
|
||||
|
||||
/*
|
||||
FacetsConfig.DimConfig ft = facetsConfig.getDimConfig(path.components[0]);
|
||||
// nocommit shouldn't we verify the indexedFieldName
|
||||
// matches what was passed to our ctor?
|
||||
FacetsConfig.DimConfig ft = config.getDimConfig(path.components[0]);
|
||||
if (ft.hierarchical && ft.multiValued) {
|
||||
totCount = counts[dimOrd];
|
||||
}
|
||||
|
@ -199,37 +184,6 @@ public class SumIntAssociationFacets extends Facets {
|
|||
labelValues[i] = new LabelAndValue(child.components[path.length], ordAndValue.value);
|
||||
}
|
||||
|
||||
return new SimpleFacetResult(path, sumValue, labelValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SimpleFacetResult> getAllDims(int topN) throws IOException {
|
||||
int ord = children[TaxonomyReader.ROOT_ORDINAL];
|
||||
List<SimpleFacetResult> results = new ArrayList<SimpleFacetResult>();
|
||||
while (ord != TaxonomyReader.INVALID_ORDINAL) {
|
||||
SimpleFacetResult result = getTopChildren(taxoReader.getPath(ord), ord, topN);
|
||||
if (result != null) {
|
||||
results.add(result);
|
||||
}
|
||||
ord = siblings[ord];
|
||||
}
|
||||
|
||||
// Sort by highest count:
|
||||
Collections.sort(results,
|
||||
new Comparator<SimpleFacetResult>() {
|
||||
@Override
|
||||
public int compare(SimpleFacetResult a, SimpleFacetResult b) {
|
||||
if (a.value.intValue() > b.value.intValue()) {
|
||||
return -1;
|
||||
} else if (b.value.intValue() > a.value.intValue()) {
|
||||
return 1;
|
||||
} else {
|
||||
// Tie break by dimension
|
||||
return a.path.components[0].compareTo(b.path.components[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
return new SimpleFacetResult(cp, sumValue, labelValues);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,29 +38,18 @@ import org.apache.lucene.util.IntsRef;
|
|||
* default encoding from {@link BinaryDocValues}. */
|
||||
|
||||
// nocommit remove & add specialized Cached variation only?
|
||||
public class TaxonomyFacetCounts extends Facets {
|
||||
public class TaxonomyFacetCounts extends TaxonomyFacets {
|
||||
private final OrdinalsReader ordinalsReader;
|
||||
private final FacetsConfig facetsConfig;
|
||||
private final TaxonomyReader taxoReader;
|
||||
private final int[] counts;
|
||||
private final int[] children;
|
||||
private final int[] parents;
|
||||
private final int[] siblings;
|
||||
|
||||
public TaxonomyFacetCounts(OrdinalsReader ordinalsReader, TaxonomyReader taxoReader, FacetsConfig facetsConfig, SimpleFacetsCollector fc) throws IOException {
|
||||
this.taxoReader = taxoReader;
|
||||
public TaxonomyFacetCounts(OrdinalsReader ordinalsReader, TaxonomyReader taxoReader, FacetsConfig config, SimpleFacetsCollector fc) throws IOException {
|
||||
super(ordinalsReader.getIndexFieldName(), taxoReader, config);
|
||||
this.ordinalsReader = ordinalsReader;
|
||||
this.facetsConfig = facetsConfig;
|
||||
ParallelTaxonomyArrays pta = taxoReader.getParallelTaxonomyArrays();
|
||||
children = pta.children();
|
||||
parents = pta.parents();
|
||||
siblings = pta.siblings();
|
||||
counts = new int[taxoReader.getSize()];
|
||||
count(fc.getMatchingDocs());
|
||||
}
|
||||
|
||||
private final void count(List<MatchingDocs> matchingDocs) throws IOException {
|
||||
//System.out.println("count matchingDocs=" + matchingDocs + " facetsField=" + facetsFieldName);
|
||||
IntsRef scratch = new IntsRef();
|
||||
for(MatchingDocs hits : matchingDocs) {
|
||||
OrdinalsReader.OrdinalsSegmentReader ords = ordinalsReader.getReader(hits.context);
|
||||
|
@ -80,13 +69,13 @@ public class TaxonomyFacetCounts extends Facets {
|
|||
// nocommit we could do this lazily instead:
|
||||
|
||||
// Rollup any necessary dims:
|
||||
for(Map.Entry<String,FacetsConfig.DimConfig> ent : facetsConfig.getDimConfigs().entrySet()) {
|
||||
for(Map.Entry<String,FacetsConfig.DimConfig> ent : config.getDimConfigs().entrySet()) {
|
||||
String dim = ent.getKey();
|
||||
FacetsConfig.DimConfig ft = ent.getValue();
|
||||
if (ft.hierarchical && ft.multiValued == false) {
|
||||
int dimRootOrd = taxoReader.getOrdinal(new FacetLabel(dim));
|
||||
// It can be -1 if this field was declared in the
|
||||
// facetsConfig but never indexed:
|
||||
// config but never indexed:
|
||||
if (dimRootOrd > 0) {
|
||||
counts[dimRootOrd] += rollup(children[dimRootOrd]);
|
||||
}
|
||||
|
@ -109,6 +98,7 @@ public class TaxonomyFacetCounts extends Facets {
|
|||
* this path doesn't exist, else the count. */
|
||||
@Override
|
||||
public Number getSpecificValue(String dim, String... path) throws IOException {
|
||||
verifyDim(dim);
|
||||
int ord = taxoReader.getOrdinal(FacetLabel.create(dim, path));
|
||||
if (ord < 0) {
|
||||
return -1;
|
||||
|
@ -118,16 +108,13 @@ public class TaxonomyFacetCounts extends Facets {
|
|||
|
||||
@Override
|
||||
public SimpleFacetResult getTopChildren(int topN, String dim, String... path) throws IOException {
|
||||
FacetsConfig.DimConfig dimConfig = verifyDim(dim);
|
||||
FacetLabel cp = FacetLabel.create(dim, path);
|
||||
int ord = taxoReader.getOrdinal(cp);
|
||||
if (ord == -1) {
|
||||
int dimOrd = taxoReader.getOrdinal(cp);
|
||||
if (dimOrd == -1) {
|
||||
//System.out.println("no ord for path=" + path);
|
||||
return null;
|
||||
}
|
||||
return getTopChildren(cp, ord, topN);
|
||||
}
|
||||
|
||||
private SimpleFacetResult getTopChildren(FacetLabel path, int dimOrd, int topN) throws IOException {
|
||||
|
||||
TopOrdAndIntQueue q = new TopOrdAndIntQueue(topN);
|
||||
|
||||
|
@ -157,14 +144,10 @@ public class TaxonomyFacetCounts extends Facets {
|
|||
}
|
||||
|
||||
if (totCount == 0) {
|
||||
//System.out.println("totCount=0 for path=" + path);
|
||||
return null;
|
||||
}
|
||||
|
||||
FacetsConfig.DimConfig ft = facetsConfig.getDimConfig(path.components[0]);
|
||||
// nocommit shouldn't we verify the indexedFieldName
|
||||
// matches what was passed to our ctor?
|
||||
if (ft.hierarchical && ft.multiValued) {
|
||||
if (dimConfig.hierarchical && dimConfig.multiValued) {
|
||||
totCount = counts[dimOrd];
|
||||
}
|
||||
|
||||
|
@ -172,40 +155,9 @@ public class TaxonomyFacetCounts extends Facets {
|
|||
for(int i=labelValues.length-1;i>=0;i--) {
|
||||
TopOrdAndIntQueue.OrdAndValue ordAndValue = q.pop();
|
||||
FacetLabel child = taxoReader.getPath(ordAndValue.ord);
|
||||
labelValues[i] = new LabelAndValue(child.components[path.length], ordAndValue.value);
|
||||
labelValues[i] = new LabelAndValue(child.components[cp.length], ordAndValue.value);
|
||||
}
|
||||
|
||||
return new SimpleFacetResult(path, totCount, labelValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SimpleFacetResult> getAllDims(int topN) throws IOException {
|
||||
int ord = children[TaxonomyReader.ROOT_ORDINAL];
|
||||
List<SimpleFacetResult> results = new ArrayList<SimpleFacetResult>();
|
||||
while (ord != TaxonomyReader.INVALID_ORDINAL) {
|
||||
SimpleFacetResult result = getTopChildren(taxoReader.getPath(ord), ord, topN);
|
||||
if (result != null) {
|
||||
results.add(result);
|
||||
}
|
||||
ord = siblings[ord];
|
||||
}
|
||||
|
||||
// Sort by highest count:
|
||||
Collections.sort(results,
|
||||
new Comparator<SimpleFacetResult>() {
|
||||
@Override
|
||||
public int compare(SimpleFacetResult a, SimpleFacetResult b) {
|
||||
if (a.value.intValue() > b.value.intValue()) {
|
||||
return -1;
|
||||
} else if (b.value.intValue() > a.value.intValue()) {
|
||||
return 1;
|
||||
} else {
|
||||
// Tie break by dimension
|
||||
return a.path.components[0].compareTo(b.path.components[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
return new SimpleFacetResult(cp, totCount, labelValues);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,29 +42,19 @@ import org.apache.lucene.util.IntsRef;
|
|||
|
||||
// nocommit jdoc that this assumes/requires the default encoding
|
||||
|
||||
public class TaxonomyFacetSumValueSource extends Facets {
|
||||
private final FacetsConfig facetsConfig;
|
||||
private final TaxonomyReader taxoReader;
|
||||
public class TaxonomyFacetSumValueSource extends TaxonomyFacets {
|
||||
private final float[] values;
|
||||
private final int[] children;
|
||||
private final int[] parents;
|
||||
private final int[] siblings;
|
||||
private final OrdinalsReader ordinalsReader;
|
||||
|
||||
public TaxonomyFacetSumValueSource(TaxonomyReader taxoReader, FacetsConfig facetsConfig,
|
||||
public TaxonomyFacetSumValueSource(TaxonomyReader taxoReader, FacetsConfig config,
|
||||
SimpleFacetsCollector fc, ValueSource valueSource) throws IOException {
|
||||
this(new DocValuesOrdinalsReader(FacetsConfig.DEFAULT_INDEXED_FIELD_NAME), taxoReader, facetsConfig, fc, valueSource);
|
||||
this(new DocValuesOrdinalsReader(FacetsConfig.DEFAULT_INDEX_FIELD_NAME), taxoReader, config, fc, valueSource);
|
||||
}
|
||||
|
||||
public TaxonomyFacetSumValueSource(OrdinalsReader ordinalsReader, TaxonomyReader taxoReader,
|
||||
FacetsConfig facetsConfig, SimpleFacetsCollector fc, ValueSource valueSource) throws IOException {
|
||||
this.taxoReader = taxoReader;
|
||||
FacetsConfig config, SimpleFacetsCollector fc, ValueSource valueSource) throws IOException {
|
||||
super(ordinalsReader.getIndexFieldName(), taxoReader, config);
|
||||
this.ordinalsReader = ordinalsReader;
|
||||
this.facetsConfig = facetsConfig;
|
||||
ParallelTaxonomyArrays pta = taxoReader.getParallelTaxonomyArrays();
|
||||
children = pta.children();
|
||||
parents = pta.parents();
|
||||
siblings = pta.siblings();
|
||||
values = new float[taxoReader.getSize()];
|
||||
sumValues(fc.getMatchingDocs(), fc.getKeepScores(), valueSource);
|
||||
}
|
||||
|
@ -113,7 +103,7 @@ public class TaxonomyFacetSumValueSource extends Facets {
|
|||
// nocommit we could do this lazily instead:
|
||||
|
||||
// Rollup any necessary dims:
|
||||
for(Map.Entry<String,FacetsConfig.DimConfig> ent : facetsConfig.getDimConfigs().entrySet()) {
|
||||
for(Map.Entry<String,FacetsConfig.DimConfig> ent : config.getDimConfigs().entrySet()) {
|
||||
String dim = ent.getKey();
|
||||
FacetsConfig.DimConfig ft = ent.getValue();
|
||||
if (ft.hierarchical && ft.multiValued == false) {
|
||||
|
@ -137,6 +127,7 @@ public class TaxonomyFacetSumValueSource extends Facets {
|
|||
|
||||
@Override
|
||||
public Number getSpecificValue(String dim, String... path) throws IOException {
|
||||
verifyDim(dim);
|
||||
int ord = taxoReader.getOrdinal(FacetLabel.create(dim, path));
|
||||
if (ord < 0) {
|
||||
return -1;
|
||||
|
@ -146,15 +137,12 @@ public class TaxonomyFacetSumValueSource extends Facets {
|
|||
|
||||
@Override
|
||||
public SimpleFacetResult getTopChildren(int topN, String dim, String... path) throws IOException {
|
||||
FacetsConfig.DimConfig dimConfig = verifyDim(dim);
|
||||
FacetLabel cp = FacetLabel.create(dim, path);
|
||||
int ord = taxoReader.getOrdinal(cp);
|
||||
if (ord == -1) {
|
||||
int dimOrd = taxoReader.getOrdinal(cp);
|
||||
if (dimOrd == -1) {
|
||||
return null;
|
||||
}
|
||||
return getTopChildren(cp, ord, topN);
|
||||
}
|
||||
|
||||
private SimpleFacetResult getTopChildren(FacetLabel path, int dimOrd, int topN) throws IOException {
|
||||
|
||||
TopOrdAndFloatQueue q = new TopOrdAndFloatQueue(topN);
|
||||
|
||||
|
@ -187,8 +175,7 @@ public class TaxonomyFacetSumValueSource extends Facets {
|
|||
return null;
|
||||
}
|
||||
|
||||
FacetsConfig.DimConfig ft = facetsConfig.getDimConfig(path.components[0]);
|
||||
if (ft.hierarchical && ft.multiValued) {
|
||||
if (dimConfig.hierarchical && dimConfig.multiValued) {
|
||||
sumValues = values[dimOrd];
|
||||
}
|
||||
|
||||
|
@ -196,40 +183,9 @@ public class TaxonomyFacetSumValueSource extends Facets {
|
|||
for(int i=labelValues.length-1;i>=0;i--) {
|
||||
TopOrdAndFloatQueue.OrdAndValue ordAndValue = q.pop();
|
||||
FacetLabel child = taxoReader.getPath(ordAndValue.ord);
|
||||
labelValues[i] = new LabelAndValue(child.components[path.length], ordAndValue.value);
|
||||
labelValues[i] = new LabelAndValue(child.components[cp.length], ordAndValue.value);
|
||||
}
|
||||
|
||||
return new SimpleFacetResult(path, sumValues, labelValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SimpleFacetResult> getAllDims(int topN) throws IOException {
|
||||
int ord = children[TaxonomyReader.ROOT_ORDINAL];
|
||||
List<SimpleFacetResult> results = new ArrayList<SimpleFacetResult>();
|
||||
while (ord != TaxonomyReader.INVALID_ORDINAL) {
|
||||
SimpleFacetResult result = getTopChildren(taxoReader.getPath(ord), ord, topN);
|
||||
if (result != null) {
|
||||
results.add(result);
|
||||
}
|
||||
ord = siblings[ord];
|
||||
}
|
||||
|
||||
// Sort by highest count:
|
||||
Collections.sort(results,
|
||||
new Comparator<SimpleFacetResult>() {
|
||||
@Override
|
||||
public int compare(SimpleFacetResult a, SimpleFacetResult b) {
|
||||
if (a.value.floatValue() > b.value.floatValue()) {
|
||||
return -1;
|
||||
} else if (b.value.floatValue() > a.value.floatValue()) {
|
||||
return 1;
|
||||
} else {
|
||||
// Tie break by dimension
|
||||
return a.path.components[0].compareTo(b.path.components[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
return new SimpleFacetResult(cp, sumValues, labelValues);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
package org.apache.lucene.facet.simple;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.facet.taxonomy.ParallelTaxonomyArrays;
|
||||
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
|
||||
|
||||
/** Base class for all taxonomy-based facets impls. */
|
||||
abstract class TaxonomyFacets extends Facets {
|
||||
protected final String indexFieldName;
|
||||
protected final TaxonomyReader taxoReader;
|
||||
protected final FacetsConfig config;
|
||||
protected final int[] children;
|
||||
protected final int[] parents;
|
||||
protected final int[] siblings;
|
||||
|
||||
/** Sole parameter is the field name that holds the facet
|
||||
* counts. */
|
||||
protected TaxonomyFacets(String indexFieldName, TaxonomyReader taxoReader, FacetsConfig config) throws IOException {
|
||||
this.indexFieldName = indexFieldName;
|
||||
this.taxoReader = taxoReader;
|
||||
this.config = config;
|
||||
ParallelTaxonomyArrays pta = taxoReader.getParallelTaxonomyArrays();
|
||||
children = pta.children();
|
||||
parents = pta.parents();
|
||||
siblings = pta.siblings();
|
||||
}
|
||||
|
||||
protected FacetsConfig.DimConfig verifyDim(String dim) {
|
||||
FacetsConfig.DimConfig dimConfig = config.getDimConfig(dim);
|
||||
if (!dimConfig.indexFieldName.equals(indexFieldName)) {
|
||||
// nocommit get test case to cover this:
|
||||
throw new IllegalArgumentException("dimension \"" + dim + "\" was not indexed into field \"" + indexFieldName);
|
||||
}
|
||||
return dimConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SimpleFacetResult> getAllDims(int topN) throws IOException {
|
||||
int ord = children[TaxonomyReader.ROOT_ORDINAL];
|
||||
List<SimpleFacetResult> results = new ArrayList<SimpleFacetResult>();
|
||||
while (ord != TaxonomyReader.INVALID_ORDINAL) {
|
||||
String dim = taxoReader.getPath(ord).components[0];
|
||||
FacetsConfig.DimConfig dimConfig = config.getDimConfig(dim);
|
||||
if (dimConfig.indexFieldName.equals(indexFieldName)) {
|
||||
SimpleFacetResult result = getTopChildren(topN, dim);
|
||||
if (result != null) {
|
||||
results.add(result);
|
||||
}
|
||||
}
|
||||
ord = siblings[ord];
|
||||
}
|
||||
|
||||
// Sort by highest value, tie break by value:
|
||||
Collections.sort(results,
|
||||
new Comparator<SimpleFacetResult>() {
|
||||
@Override
|
||||
public int compare(SimpleFacetResult a, SimpleFacetResult b) {
|
||||
if (a.value.doubleValue() > b.value.doubleValue()) {
|
||||
return -1;
|
||||
} else if (b.value.doubleValue() > a.value.doubleValue()) {
|
||||
return 1;
|
||||
} else {
|
||||
// Tie break by dimension
|
||||
return a.path.components[0].compareTo(b.path.components[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
|
@ -49,11 +49,13 @@ public class TestAssociationFacets extends FacetTestCase {
|
|||
private static Directory dir;
|
||||
private static IndexReader reader;
|
||||
private static Directory taxoDir;
|
||||
|
||||
private static TaxonomyReader taxoReader;
|
||||
|
||||
private static final FacetLabel aint = new FacetLabel("int", "a");
|
||||
private static final FacetLabel bint = new FacetLabel("int", "b");
|
||||
private static final FacetLabel afloat = new FacetLabel("float", "a");
|
||||
private static final FacetLabel bfloat = new FacetLabel("float", "b");
|
||||
private static final FacetsConfig config = new FacetsConfig();
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
|
@ -63,8 +65,12 @@ public class TestAssociationFacets extends FacetTestCase {
|
|||
|
||||
TaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir);
|
||||
|
||||
// Cannot mix ints & floats in the same indexed field:
|
||||
config.setIndexFieldName("int", "$facets.int");
|
||||
config.setIndexFieldName("float", "$facets.float");
|
||||
|
||||
IndexWriterConfig iwc = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()));
|
||||
IndexWriter writer = new FacetIndexWriter(dir, iwc, taxoWriter, new FacetsConfig());
|
||||
IndexWriter writer = new FacetIndexWriter(dir, iwc, taxoWriter, config);
|
||||
|
||||
// index documents, 50% have only 'b' and all have 'a'
|
||||
for (int i = 0; i < 110; i++) {
|
||||
|
@ -85,6 +91,7 @@ public class TestAssociationFacets extends FacetTestCase {
|
|||
taxoWriter.close();
|
||||
reader = DirectoryReader.open(writer, true);
|
||||
writer.close();
|
||||
taxoReader = new DirectoryTaxonomyReader(taxoDir);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
@ -93,67 +100,71 @@ public class TestAssociationFacets extends FacetTestCase {
|
|||
reader = null;
|
||||
dir.close();
|
||||
dir = null;
|
||||
taxoReader.close();
|
||||
taxoReader = null;
|
||||
taxoDir.close();
|
||||
taxoDir = null;
|
||||
}
|
||||
|
||||
public void testIntSumAssociation() throws Exception {
|
||||
TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
|
||||
|
||||
SimpleFacetsCollector fc = new SimpleFacetsCollector();
|
||||
|
||||
IndexSearcher searcher = newSearcher(reader);
|
||||
searcher.search(new MatchAllDocsQuery(), fc);
|
||||
|
||||
SumIntAssociationFacets facets = new SumIntAssociationFacets(taxoReader, new FacetsConfig(), fc);
|
||||
Facets facets = new SumIntAssociationFacets("$facets.int", taxoReader, config, fc);
|
||||
|
||||
assertEquals("Wrong count for category 'a'!", 200, facets.getSpecificValue("int", "a").intValue());
|
||||
assertEquals("Wrong count for category 'b'!", 150, facets.getSpecificValue("int", "b").intValue());
|
||||
|
||||
taxoReader.close();
|
||||
}
|
||||
|
||||
public void testFloatSumAssociation() throws Exception {
|
||||
DirectoryTaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
|
||||
|
||||
SimpleFacetsCollector fc = new SimpleFacetsCollector();
|
||||
|
||||
IndexSearcher searcher = newSearcher(reader);
|
||||
searcher.search(new MatchAllDocsQuery(), fc);
|
||||
|
||||
SumFloatAssociationFacets facets = new SumFloatAssociationFacets(taxoReader, new FacetsConfig(), fc);
|
||||
Facets facets = new SumFloatAssociationFacets("$facets.float", taxoReader, config, fc);
|
||||
assertEquals("Wrong count for category 'a'!", 50f, facets.getSpecificValue("float", "a").floatValue(), 0.00001);
|
||||
assertEquals("Wrong count for category 'b'!", 10f, facets.getSpecificValue("float", "b").floatValue(), 0.00001);
|
||||
}
|
||||
|
||||
/** Make sure we can test both int and float assocs in one
|
||||
* index, as long as we send each to a different field. */
|
||||
public void testIntAndFloatAssocation() throws Exception {
|
||||
SimpleFacetsCollector fc = new SimpleFacetsCollector();
|
||||
|
||||
IndexSearcher searcher = newSearcher(reader);
|
||||
searcher.search(new MatchAllDocsQuery(), fc);
|
||||
|
||||
Facets facets = new SumFloatAssociationFacets("$facets.float", taxoReader, config, fc);
|
||||
assertEquals("Wrong count for category 'a'!", 50f, facets.getSpecificValue("float", "a").floatValue(), 0.00001);
|
||||
assertEquals("Wrong count for category 'b'!", 10f, facets.getSpecificValue("float", "b").floatValue(), 0.00001);
|
||||
|
||||
taxoReader.close();
|
||||
}
|
||||
facets = new SumIntAssociationFacets("$facets.int", taxoReader, config, fc);
|
||||
assertEquals("Wrong count for category 'a'!", 200, facets.getSpecificValue("int", "a").intValue());
|
||||
assertEquals("Wrong count for category 'b'!", 150, facets.getSpecificValue("int", "b").intValue());
|
||||
}
|
||||
|
||||
/*
|
||||
public void testDifferentAggregatorsSameCategoryList() throws Exception {
|
||||
DirectoryTaxonomyReader taxo = new DirectoryTaxonomyReader(taxoDir);
|
||||
|
||||
// facet requests for two facets
|
||||
FacetSearchParams fsp = new FacetSearchParams(
|
||||
new SumIntAssociationFacetRequest(aint, 10),
|
||||
new SumIntAssociationFacetRequest(bint, 10),
|
||||
new SumFloatAssociationFacetRequest(afloat, 10),
|
||||
new SumFloatAssociationFacetRequest(bfloat, 10));
|
||||
|
||||
Query q = new MatchAllDocsQuery();
|
||||
|
||||
FacetsCollector fc = FacetsCollector.create(fsp, reader, taxo);
|
||||
public void testWrongIndexFieldName() throws Exception {
|
||||
SimpleFacetsCollector fc = new SimpleFacetsCollector();
|
||||
|
||||
IndexSearcher searcher = newSearcher(reader);
|
||||
searcher.search(q, fc);
|
||||
List<FacetResult> res = fc.getFacetResults();
|
||||
|
||||
assertEquals("Wrong number of results!", 4, res.size());
|
||||
assertEquals("Wrong count for category 'a'!", 200, (int) res.get(0).getFacetResultNode().value);
|
||||
assertEquals("Wrong count for category 'b'!", 150, (int) res.get(1).getFacetResultNode().value);
|
||||
assertEquals("Wrong count for category 'a'!",50f, (float) res.get(2).getFacetResultNode().value, 0.00001);
|
||||
assertEquals("Wrong count for category 'b'!",10f, (float) res.get(3).getFacetResultNode().value, 0.00001);
|
||||
|
||||
taxo.close();
|
||||
searcher.search(new MatchAllDocsQuery(), fc);
|
||||
Facets facets = new SumFloatAssociationFacets(taxoReader, config, fc);
|
||||
try {
|
||||
facets.getSpecificValue("float");
|
||||
fail("should have hit exc");
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// expected
|
||||
}
|
||||
|
||||
try {
|
||||
facets.getTopChildren(10, "float");
|
||||
fail("should have hit exc");
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -208,6 +208,70 @@ public class TestTaxonomyFacets extends FacetTestCase {
|
|||
dir.close();
|
||||
}
|
||||
|
||||
public void testWrongIndexFieldName() throws Exception {
|
||||
Directory dir = newDirectory();
|
||||
Directory taxoDir = newDirectory();
|
||||
|
||||
// Writes facet ords to a separate directory from the
|
||||
// main index:
|
||||
DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir, IndexWriterConfig.OpenMode.CREATE);
|
||||
|
||||
FacetsConfig config = new FacetsConfig();
|
||||
config.setIndexFieldName("a", "$facets2");
|
||||
IndexWriter writer = new FacetIndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())), taxoWriter, config);
|
||||
|
||||
Document doc = new Document();
|
||||
doc.add(new FacetField("a", "foo1"));
|
||||
writer.addDocument(doc);
|
||||
|
||||
// NRT open
|
||||
IndexSearcher searcher = newSearcher(DirectoryReader.open(writer, true));
|
||||
writer.close();
|
||||
|
||||
// NRT open
|
||||
TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoWriter);
|
||||
taxoWriter.close();
|
||||
|
||||
SimpleFacetsCollector c = new SimpleFacetsCollector();
|
||||
searcher.search(new MatchAllDocsQuery(), c);
|
||||
|
||||
// Uses default $facets field:
|
||||
Facets facets;
|
||||
if (random().nextBoolean()) {
|
||||
facets = new FastTaxonomyFacetCounts(taxoReader, config, c);
|
||||
} else {
|
||||
OrdinalsReader ordsReader = new DocValuesOrdinalsReader();
|
||||
if (random().nextBoolean()) {
|
||||
ordsReader = new CachedOrdinalsReader(ordsReader);
|
||||
}
|
||||
facets = new TaxonomyFacetCounts(ordsReader, taxoReader, config, c);
|
||||
}
|
||||
|
||||
// Ask for top 10 labels for any dims that have counts:
|
||||
List<SimpleFacetResult> results = facets.getAllDims(10);
|
||||
assertTrue(results.isEmpty());
|
||||
|
||||
try {
|
||||
facets.getSpecificValue("a");
|
||||
fail("should have hit exc");
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// expected
|
||||
}
|
||||
|
||||
try {
|
||||
facets.getTopChildren(10, "a");
|
||||
fail("should have hit exc");
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// expected
|
||||
}
|
||||
|
||||
searcher.getIndexReader().close();
|
||||
taxoReader.close();
|
||||
taxoDir.close();
|
||||
dir.close();
|
||||
}
|
||||
|
||||
|
||||
// nocommit in the sparse case test that we are really
|
||||
// sorting by the correct dim count
|
||||
|
||||
|
|
|
@ -184,6 +184,62 @@ public class TestTaxonomyFacetsSumValueSource extends FacetTestCase {
|
|||
dir.close();
|
||||
}
|
||||
|
||||
public void testWrongIndexFieldName() throws Exception {
|
||||
|
||||
Directory dir = newDirectory();
|
||||
Directory taxoDir = newDirectory();
|
||||
|
||||
// Writes facet ords to a separate directory from the
|
||||
// main index:
|
||||
DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir, IndexWriterConfig.OpenMode.CREATE);
|
||||
|
||||
FacetsConfig config = new FacetsConfig();
|
||||
config.setIndexFieldName("a", "$facets2");
|
||||
|
||||
IndexWriter writer = new FacetIndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())), taxoWriter, config);
|
||||
|
||||
Document doc = new Document();
|
||||
doc.add(new IntField("num", 10, Field.Store.NO));
|
||||
doc.add(new FacetField("a", "foo1"));
|
||||
writer.addDocument(doc);
|
||||
|
||||
// NRT open
|
||||
IndexSearcher searcher = newSearcher(DirectoryReader.open(writer, true));
|
||||
writer.close();
|
||||
|
||||
// NRT open
|
||||
TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoWriter);
|
||||
taxoWriter.close();
|
||||
|
||||
SimpleFacetsCollector c = new SimpleFacetsCollector();
|
||||
searcher.search(new MatchAllDocsQuery(), c);
|
||||
|
||||
TaxonomyFacetSumValueSource facets = new TaxonomyFacetSumValueSource(taxoReader, config, c, new IntFieldSource("num"));
|
||||
|
||||
// Ask for top 10 labels for any dims that have counts:
|
||||
List<SimpleFacetResult> results = facets.getAllDims(10);
|
||||
assertTrue(results.isEmpty());
|
||||
|
||||
try {
|
||||
facets.getSpecificValue("a");
|
||||
fail("should have hit exc");
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// expected
|
||||
}
|
||||
|
||||
try {
|
||||
facets.getTopChildren(10, "a");
|
||||
fail("should have hit exc");
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// expected
|
||||
}
|
||||
|
||||
searcher.getIndexReader().close();
|
||||
taxoReader.close();
|
||||
taxoDir.close();
|
||||
dir.close();
|
||||
}
|
||||
|
||||
// nocommit in the sparse case test that we are really
|
||||
// sorting by the correct dim count
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue