terms stats to use new field data
This commit is contained in:
parent
f1f86efed5
commit
37acba1b57
|
@ -73,4 +73,14 @@ public class HashedBytesRef {
|
|||
public String toString() {
|
||||
return bytes.toString();
|
||||
}
|
||||
|
||||
public HashedBytesRef deepCopy() {
|
||||
return deepCopyOf(this);
|
||||
}
|
||||
|
||||
public static HashedBytesRef deepCopyOf(HashedBytesRef other) {
|
||||
BytesRef copy = new BytesRef();
|
||||
copy.copyBytes(other.bytes);
|
||||
return new HashedBytesRef(copy, other.hash);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,12 +26,44 @@ import org.apache.lucene.index.AtomicReaderContext;
|
|||
public interface IndexNumericFieldData<FD extends AtomicNumericFieldData> extends IndexFieldData<FD> {
|
||||
|
||||
static enum NumericType {
|
||||
BYTE,
|
||||
SHORT,
|
||||
INT,
|
||||
LONG,
|
||||
FLOAT,
|
||||
DOUBLE
|
||||
BYTE {
|
||||
@Override
|
||||
public boolean isFloatingPoint() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
SHORT {
|
||||
@Override
|
||||
public boolean isFloatingPoint() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
INT {
|
||||
@Override
|
||||
public boolean isFloatingPoint() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
LONG {
|
||||
@Override
|
||||
public boolean isFloatingPoint() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
FLOAT {
|
||||
@Override
|
||||
public boolean isFloatingPoint() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
DOUBLE {
|
||||
@Override
|
||||
public boolean isFloatingPoint() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
public abstract boolean isFloatingPoint();
|
||||
}
|
||||
|
||||
NumericType getNumericType();
|
||||
|
|
|
@ -54,7 +54,7 @@ public class LongArrayIndexFieldData extends AbstractIndexFieldData<LongArrayAto
|
|||
|
||||
@Override
|
||||
public NumericType getNumericType() {
|
||||
return NumericType.DOUBLE;
|
||||
return NumericType.LONG;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,8 +23,10 @@ import org.elasticsearch.common.component.AbstractComponent;
|
|||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.field.data.FieldDataType;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
import org.elasticsearch.search.facet.Facet;
|
||||
import org.elasticsearch.search.facet.FacetCollector;
|
||||
import org.elasticsearch.search.facet.FacetPhaseExecutionException;
|
||||
|
@ -102,24 +104,29 @@ public class TermsStatsFacetProcessor extends AbstractComponent implements Facet
|
|||
throw new FacetPhaseExecutionException(facetName, "either [value_field] or [script] are required to be set for terms stats facet");
|
||||
}
|
||||
|
||||
FieldMapper keyFieldMapper = context.smartNameFieldMapper(keyField);
|
||||
if (keyFieldMapper != null) {
|
||||
if (keyFieldMapper.fieldDataType() == FieldDataType.DefaultTypes.LONG) {
|
||||
return new TermsStatsLongFacetCollector(facetName, keyField, valueField, size, comparatorType, context, scriptLang, script, params);
|
||||
} else if (keyFieldMapper.fieldDataType() == FieldDataType.DefaultTypes.INT) {
|
||||
return new TermsStatsLongFacetCollector(facetName, keyField, valueField, size, comparatorType, context, scriptLang, script, params);
|
||||
} else if (keyFieldMapper.fieldDataType() == FieldDataType.DefaultTypes.SHORT) {
|
||||
return new TermsStatsLongFacetCollector(facetName, keyField, valueField, size, comparatorType, context, scriptLang, script, params);
|
||||
} else if (keyFieldMapper.fieldDataType() == FieldDataType.DefaultTypes.BYTE) {
|
||||
return new TermsStatsLongFacetCollector(facetName, keyField, valueField, size, comparatorType, context, scriptLang, script, params);
|
||||
} else if (keyFieldMapper.fieldDataType() == FieldDataType.DefaultTypes.DOUBLE) {
|
||||
return new TermsStatsDoubleFacetCollector(facetName, keyField, valueField, size, comparatorType, context, scriptLang, script, params);
|
||||
} else if (keyFieldMapper.fieldDataType() == FieldDataType.DefaultTypes.FLOAT) {
|
||||
return new TermsStatsDoubleFacetCollector(facetName, keyField, valueField, size, comparatorType, context, scriptLang, script, params);
|
||||
FieldMapper keyMapper = context.smartNameFieldMapper(keyField);
|
||||
if (keyMapper == null) {
|
||||
throw new FacetPhaseExecutionException(facetName, "failed to find mapping for " + keyField);
|
||||
}
|
||||
IndexFieldData keyIndexFieldData = context.fieldData().getForField(keyMapper);
|
||||
|
||||
IndexNumericFieldData valueIndexFieldData = null;
|
||||
SearchScript valueScript = null;
|
||||
if (valueField != null) {
|
||||
valueIndexFieldData = context.fieldData().getForField(context.smartNameFieldMapper(valueField));
|
||||
} else {
|
||||
valueScript = context.scriptService().search(context.lookup(), scriptLang, script, params);
|
||||
}
|
||||
|
||||
return new TermsStatsStringFacetCollector(facetName, keyField, valueField, size, comparatorType, context, scriptLang, script, params);
|
||||
if (keyIndexFieldData instanceof IndexNumericFieldData) {
|
||||
IndexNumericFieldData keyIndexNumericFieldData = (IndexNumericFieldData) keyIndexFieldData;
|
||||
if (keyIndexNumericFieldData.getNumericType().isFloatingPoint()) {
|
||||
return new TermsStatsDoubleFacetCollector(facetName, keyIndexNumericFieldData, valueIndexFieldData, valueScript, size, comparatorType, context);
|
||||
} else {
|
||||
return new TermsStatsLongFacetCollector(facetName, keyIndexNumericFieldData, valueIndexFieldData, valueScript, size, comparatorType, context);
|
||||
}
|
||||
}
|
||||
return new TermsStatsStringFacetCollector(facetName, keyIndexFieldData, valueIndexFieldData, valueScript, size, comparatorType, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,13 +23,10 @@ import com.google.common.collect.ImmutableList;
|
|||
import com.google.common.collect.Lists;
|
||||
import org.apache.lucene.index.AtomicReaderContext;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||
import org.elasticsearch.common.CacheRecycler;
|
||||
import org.elasticsearch.common.trove.ExtTDoubleObjectHashMap;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.FieldDataType;
|
||||
import org.elasticsearch.index.field.data.NumericFieldData;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.fielddata.DoubleValues;
|
||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
import org.elasticsearch.search.facet.AbstractFacetCollector;
|
||||
import org.elasticsearch.search.facet.Facet;
|
||||
|
@ -40,67 +37,35 @@ import java.io.IOException;
|
|||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TermsStatsDoubleFacetCollector extends AbstractFacetCollector {
|
||||
|
||||
private final TermsStatsFacet.ComparatorType comparatorType;
|
||||
|
||||
private final FieldDataCache fieldDataCache;
|
||||
|
||||
private final String keyFieldName;
|
||||
|
||||
private final String valueFieldName;
|
||||
private final IndexNumericFieldData keyIndexFieldData;
|
||||
private final IndexNumericFieldData valueIndexFieldData;
|
||||
private final SearchScript script;
|
||||
|
||||
private final int size;
|
||||
|
||||
private final int numberOfShards;
|
||||
|
||||
private final FieldDataType keyFieldDataType;
|
||||
|
||||
private NumericFieldData keyFieldData;
|
||||
|
||||
private final FieldDataType valueFieldDataType;
|
||||
|
||||
private final SearchScript script;
|
||||
|
||||
private final Aggregator aggregator;
|
||||
|
||||
public TermsStatsDoubleFacetCollector(String facetName, String keyFieldName, String valueFieldName, int size, TermsStatsFacet.ComparatorType comparatorType,
|
||||
SearchContext context, String scriptLang, String script, Map<String, Object> params) {
|
||||
private DoubleValues keyValues;
|
||||
|
||||
public TermsStatsDoubleFacetCollector(String facetName, IndexNumericFieldData keyIndexFieldData, IndexNumericFieldData valueIndexFieldData, SearchScript script,
|
||||
int size, TermsStatsFacet.ComparatorType comparatorType, SearchContext context) {
|
||||
super(facetName);
|
||||
this.fieldDataCache = context.fieldDataCache();
|
||||
this.size = size;
|
||||
this.comparatorType = comparatorType;
|
||||
this.numberOfShards = context.numberOfShards();
|
||||
|
||||
MapperService.SmartNameFieldMappers smartMappers = context.smartFieldMappers(keyFieldName);
|
||||
if (smartMappers == null || !smartMappers.hasMapper()) {
|
||||
this.keyFieldName = keyFieldName;
|
||||
this.keyFieldDataType = FieldDataType.DefaultTypes.STRING;
|
||||
} else {
|
||||
// add type filter if there is exact doc mapper associated with it
|
||||
if (smartMappers.explicitTypeInNameWithDocMapper()) {
|
||||
setFilter(context.filterCache().cache(smartMappers.docMapper().typeFilter()));
|
||||
}
|
||||
|
||||
this.keyFieldName = smartMappers.mapper().names().indexName();
|
||||
this.keyFieldDataType = smartMappers.mapper().fieldDataType();
|
||||
}
|
||||
this.keyIndexFieldData = keyIndexFieldData;
|
||||
this.valueIndexFieldData = valueIndexFieldData;
|
||||
this.script = script;
|
||||
|
||||
if (script == null) {
|
||||
smartMappers = context.smartFieldMappers(valueFieldName);
|
||||
if (smartMappers == null || !smartMappers.hasMapper()) {
|
||||
throw new ElasticSearchIllegalArgumentException("failed to find mappings for [" + valueFieldName + "]");
|
||||
}
|
||||
this.valueFieldName = smartMappers.mapper().names().indexName();
|
||||
this.valueFieldDataType = smartMappers.mapper().fieldDataType();
|
||||
this.script = null;
|
||||
this.aggregator = new Aggregator();
|
||||
} else {
|
||||
this.valueFieldName = null;
|
||||
this.valueFieldDataType = null;
|
||||
this.script = context.scriptService().search(context.lookup(), scriptLang, script, params);
|
||||
this.aggregator = new ScriptAggregator(this.script);
|
||||
}
|
||||
}
|
||||
|
@ -114,17 +79,17 @@ public class TermsStatsDoubleFacetCollector extends AbstractFacetCollector {
|
|||
|
||||
@Override
|
||||
protected void doSetNextReader(AtomicReaderContext context) throws IOException {
|
||||
keyFieldData = (NumericFieldData) fieldDataCache.cache(keyFieldDataType, context.reader(), keyFieldName);
|
||||
keyValues = keyIndexFieldData.load(context).getDoubleValues();
|
||||
if (script != null) {
|
||||
script.setNextReader(context);
|
||||
} else {
|
||||
aggregator.valueFieldData = (NumericFieldData) fieldDataCache.cache(valueFieldDataType, context.reader(), valueFieldName);
|
||||
aggregator.valueFieldData = valueIndexFieldData.load(context).getDoubleValues();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doCollect(int doc) throws IOException {
|
||||
keyFieldData.forEachValueInDoc(doc, aggregator);
|
||||
keyValues.forEachValueInDoc(doc, aggregator);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -153,12 +118,12 @@ public class TermsStatsDoubleFacetCollector extends AbstractFacetCollector {
|
|||
return new InternalTermsStatsDoubleFacet(facetName, comparatorType, size, ordered, aggregator.missing);
|
||||
}
|
||||
|
||||
public static class Aggregator implements NumericFieldData.MissingDoubleValueInDocProc {
|
||||
public static class Aggregator implements DoubleValues.ValueInDocProc {
|
||||
|
||||
final ExtTDoubleObjectHashMap<InternalTermsStatsDoubleFacet.DoubleEntry> entries = CacheRecycler.popDoubleObjectMap();
|
||||
int missing;
|
||||
|
||||
NumericFieldData valueFieldData;
|
||||
DoubleValues valueFieldData;
|
||||
|
||||
final ValueAggregator valueAggregator = new ValueAggregator();
|
||||
|
||||
|
@ -179,10 +144,14 @@ public class TermsStatsDoubleFacetCollector extends AbstractFacetCollector {
|
|||
missing++;
|
||||
}
|
||||
|
||||
public static class ValueAggregator implements NumericFieldData.DoubleValueInDocProc {
|
||||
public static class ValueAggregator implements DoubleValues.ValueInDocProc {
|
||||
|
||||
InternalTermsStatsDoubleFacet.DoubleEntry doubleEntry;
|
||||
|
||||
@Override
|
||||
public void onMissing(int docId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValue(int docId, double value) {
|
||||
if (value < doubleEntry.min) {
|
||||
|
|
|
@ -23,13 +23,11 @@ import com.google.common.collect.ImmutableList;
|
|||
import com.google.common.collect.Lists;
|
||||
import org.apache.lucene.index.AtomicReaderContext;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||
import org.elasticsearch.common.CacheRecycler;
|
||||
import org.elasticsearch.common.trove.ExtTLongObjectHashMap;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.FieldDataType;
|
||||
import org.elasticsearch.index.field.data.NumericFieldData;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.fielddata.DoubleValues;
|
||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.LongValues;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
import org.elasticsearch.search.facet.AbstractFacetCollector;
|
||||
import org.elasticsearch.search.facet.Facet;
|
||||
|
@ -40,68 +38,35 @@ import java.io.IOException;
|
|||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TermsStatsLongFacetCollector extends AbstractFacetCollector {
|
||||
|
||||
private final TermsStatsFacet.ComparatorType comparatorType;
|
||||
|
||||
private final FieldDataCache fieldDataCache;
|
||||
|
||||
private final String keyFieldName;
|
||||
|
||||
private final String valueFieldName;
|
||||
|
||||
private final int size;
|
||||
|
||||
private final int numberOfShards;
|
||||
|
||||
private final FieldDataType keyFieldDataType;
|
||||
|
||||
private NumericFieldData keyFieldData;
|
||||
|
||||
private final FieldDataType valueFieldDataType;
|
||||
|
||||
private final IndexNumericFieldData keyIndexFieldData;
|
||||
private final IndexNumericFieldData valueIndexFieldData;
|
||||
private final SearchScript script;
|
||||
|
||||
private final int size;
|
||||
private final int numberOfShards;
|
||||
|
||||
private final Aggregator aggregator;
|
||||
|
||||
public TermsStatsLongFacetCollector(String facetName, String keyFieldName, String valueFieldName, int size, TermsStatsFacet.ComparatorType comparatorType,
|
||||
SearchContext context, String scriptLang, String script, Map<String, Object> params) {
|
||||
private LongValues keyValues;
|
||||
|
||||
public TermsStatsLongFacetCollector(String facetName, IndexNumericFieldData keyIndexFieldData, IndexNumericFieldData valueIndexFieldData, SearchScript script,
|
||||
int size, TermsStatsFacet.ComparatorType comparatorType, SearchContext context) {
|
||||
super(facetName);
|
||||
this.fieldDataCache = context.fieldDataCache();
|
||||
this.size = size;
|
||||
this.comparatorType = comparatorType;
|
||||
this.numberOfShards = context.numberOfShards();
|
||||
|
||||
MapperService.SmartNameFieldMappers smartMappers = context.smartFieldMappers(keyFieldName);
|
||||
if (smartMappers == null || !smartMappers.hasMapper()) {
|
||||
this.keyFieldName = keyFieldName;
|
||||
this.keyFieldDataType = FieldDataType.DefaultTypes.STRING;
|
||||
} else {
|
||||
// add type filter if there is exact doc mapper associated with it
|
||||
if (smartMappers.explicitTypeInNameWithDocMapper()) {
|
||||
setFilter(context.filterCache().cache(smartMappers.docMapper().typeFilter()));
|
||||
}
|
||||
|
||||
this.keyFieldName = smartMappers.mapper().names().indexName();
|
||||
this.keyFieldDataType = smartMappers.mapper().fieldDataType();
|
||||
}
|
||||
this.keyIndexFieldData = keyIndexFieldData;
|
||||
this.valueIndexFieldData = valueIndexFieldData;
|
||||
this.script = script;
|
||||
|
||||
if (script == null) {
|
||||
smartMappers = context.smartFieldMappers(valueFieldName);
|
||||
if (smartMappers == null || !smartMappers.hasMapper()) {
|
||||
throw new ElasticSearchIllegalArgumentException("failed to find mappings for [" + valueFieldName + "]");
|
||||
}
|
||||
this.valueFieldName = smartMappers.mapper().names().indexName();
|
||||
this.valueFieldDataType = smartMappers.mapper().fieldDataType();
|
||||
this.script = null;
|
||||
this.aggregator = new Aggregator();
|
||||
} else {
|
||||
this.valueFieldName = null;
|
||||
this.valueFieldDataType = null;
|
||||
this.script = context.scriptService().search(context.lookup(), scriptLang, script, params);
|
||||
this.aggregator = new ScriptAggregator(this.script);
|
||||
}
|
||||
}
|
||||
|
@ -115,17 +80,17 @@ public class TermsStatsLongFacetCollector extends AbstractFacetCollector {
|
|||
|
||||
@Override
|
||||
protected void doSetNextReader(AtomicReaderContext context) throws IOException {
|
||||
keyFieldData = (NumericFieldData) fieldDataCache.cache(keyFieldDataType, context.reader(), keyFieldName);
|
||||
keyValues = keyIndexFieldData.load(context).getLongValues();
|
||||
if (script != null) {
|
||||
script.setNextReader(context);
|
||||
} else {
|
||||
aggregator.valueFieldData = (NumericFieldData) fieldDataCache.cache(valueFieldDataType, context.reader(), valueFieldName);
|
||||
aggregator.valueValues = valueIndexFieldData.load(context).getDoubleValues();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doCollect(int doc) throws IOException {
|
||||
keyFieldData.forEachValueInDoc(doc, aggregator);
|
||||
keyValues.forEachValueInDoc(doc, aggregator);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -155,13 +120,13 @@ public class TermsStatsLongFacetCollector extends AbstractFacetCollector {
|
|||
return new InternalTermsStatsLongFacet(facetName, comparatorType, size, ordered, aggregator.missing);
|
||||
}
|
||||
|
||||
public static class Aggregator implements NumericFieldData.MissingLongValueInDocProc {
|
||||
public static class Aggregator implements LongValues.ValueInDocProc {
|
||||
|
||||
final ExtTLongObjectHashMap<InternalTermsStatsLongFacet.LongEntry> entries = CacheRecycler.popLongObjectMap();
|
||||
|
||||
int missing;
|
||||
|
||||
NumericFieldData valueFieldData;
|
||||
DoubleValues valueValues;
|
||||
|
||||
final ValueAggregator valueAggregator = new ValueAggregator();
|
||||
|
||||
|
@ -174,7 +139,7 @@ public class TermsStatsLongFacetCollector extends AbstractFacetCollector {
|
|||
}
|
||||
longEntry.count++;
|
||||
valueAggregator.longEntry = longEntry;
|
||||
valueFieldData.forEachValueInDoc(docId, valueAggregator);
|
||||
valueValues.forEachValueInDoc(docId, valueAggregator);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -182,10 +147,14 @@ public class TermsStatsLongFacetCollector extends AbstractFacetCollector {
|
|||
missing++;
|
||||
}
|
||||
|
||||
public static class ValueAggregator implements NumericFieldData.DoubleValueInDocProc {
|
||||
public static class ValueAggregator implements DoubleValues.ValueInDocProc {
|
||||
|
||||
InternalTermsStatsLongFacet.LongEntry longEntry;
|
||||
|
||||
@Override
|
||||
public void onMissing(int docId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValue(int docId, double value) {
|
||||
if (value < longEntry.min) {
|
||||
|
|
|
@ -20,12 +20,11 @@
|
|||
package org.elasticsearch.search.facet.termsstats.strings;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.elasticsearch.common.CacheRecycler;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.lucene.HashedBytesRef;
|
||||
import org.elasticsearch.common.text.BytesText;
|
||||
import org.elasticsearch.common.text.Text;
|
||||
import org.elasticsearch.common.trove.ExtTHashMap;
|
||||
|
@ -69,8 +68,8 @@ public class InternalTermsStatsStringFacet extends InternalTermsStatsFacet {
|
|||
double min;
|
||||
double max;
|
||||
|
||||
public StringEntry(BytesRef term, long count, long totalCount, double total, double min, double max) {
|
||||
this(new BytesText(new BytesArray(term)), count, totalCount, total, min, max);
|
||||
public StringEntry(HashedBytesRef term, long count, long totalCount, double total, double min, double max) {
|
||||
this(new BytesText(new BytesArray(term.bytes)), count, totalCount, total, min, max);
|
||||
}
|
||||
|
||||
public StringEntry(Text term, long count, long totalCount, double total, double min, double max) {
|
||||
|
|
|
@ -23,15 +23,13 @@ import com.google.common.collect.ImmutableList;
|
|||
import com.google.common.collect.Lists;
|
||||
import org.apache.lucene.index.AtomicReaderContext;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||
import org.elasticsearch.common.CacheRecycler;
|
||||
import org.elasticsearch.common.lucene.HashedBytesRef;
|
||||
import org.elasticsearch.common.trove.ExtTHashMap;
|
||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||
import org.elasticsearch.index.field.data.FieldData;
|
||||
import org.elasticsearch.index.field.data.FieldDataType;
|
||||
import org.elasticsearch.index.field.data.NumericFieldData;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.fielddata.DoubleValues;
|
||||
import org.elasticsearch.index.fielddata.HashedBytesValues;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
import org.elasticsearch.search.facet.AbstractFacetCollector;
|
||||
import org.elasticsearch.search.facet.Facet;
|
||||
|
@ -42,68 +40,36 @@ import java.io.IOException;
|
|||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
|
||||
|
||||
private final TermsStatsFacet.ComparatorType comparatorType;
|
||||
|
||||
private final FieldDataCache fieldDataCache;
|
||||
|
||||
private final String keyFieldName;
|
||||
|
||||
private final String valueFieldName;
|
||||
private final IndexFieldData keyIndexFieldData;
|
||||
private final IndexNumericFieldData valueIndexFieldData;
|
||||
private final SearchScript script;
|
||||
|
||||
private final int size;
|
||||
|
||||
private final int numberOfShards;
|
||||
|
||||
private final FieldDataType keyFieldDataType;
|
||||
|
||||
private FieldData keyFieldData;
|
||||
|
||||
private final FieldDataType valueFieldDataType;
|
||||
|
||||
private final SearchScript script;
|
||||
|
||||
private final Aggregator aggregator;
|
||||
|
||||
public TermsStatsStringFacetCollector(String facetName, String keyFieldName, String valueFieldName, int size, TermsStatsFacet.ComparatorType comparatorType,
|
||||
SearchContext context, String scriptLang, String script, Map<String, Object> params) {
|
||||
private HashedBytesValues keyValues;
|
||||
|
||||
public TermsStatsStringFacetCollector(String facetName, IndexFieldData keyIndexFieldData, IndexNumericFieldData valueIndexFieldData, SearchScript valueScript,
|
||||
int size, TermsStatsFacet.ComparatorType comparatorType, SearchContext context) {
|
||||
super(facetName);
|
||||
this.fieldDataCache = context.fieldDataCache();
|
||||
this.keyIndexFieldData = keyIndexFieldData;
|
||||
this.valueIndexFieldData = valueIndexFieldData;
|
||||
this.script = valueScript;
|
||||
this.size = size;
|
||||
this.comparatorType = comparatorType;
|
||||
this.numberOfShards = context.numberOfShards();
|
||||
|
||||
MapperService.SmartNameFieldMappers smartMappers = context.smartFieldMappers(keyFieldName);
|
||||
if (smartMappers == null || !smartMappers.hasMapper()) {
|
||||
this.keyFieldName = keyFieldName;
|
||||
this.keyFieldDataType = FieldDataType.DefaultTypes.STRING;
|
||||
if (script != null) {
|
||||
this.aggregator = new ScriptAggregator(valueScript);
|
||||
} else {
|
||||
// add type filter if there is exact doc mapper associated with it
|
||||
if (smartMappers.explicitTypeInNameWithDocMapper()) {
|
||||
setFilter(context.filterCache().cache(smartMappers.docMapper().typeFilter()));
|
||||
}
|
||||
|
||||
this.keyFieldName = smartMappers.mapper().names().indexName();
|
||||
this.keyFieldDataType = smartMappers.mapper().fieldDataType();
|
||||
}
|
||||
|
||||
if (script == null) {
|
||||
smartMappers = context.smartFieldMappers(valueFieldName);
|
||||
if (smartMappers == null || !smartMappers.hasMapper()) {
|
||||
throw new ElasticSearchIllegalArgumentException("failed to find mappings for [" + valueFieldName + "]");
|
||||
}
|
||||
this.valueFieldName = smartMappers.mapper().names().indexName();
|
||||
this.valueFieldDataType = smartMappers.mapper().fieldDataType();
|
||||
this.script = null;
|
||||
this.aggregator = new Aggregator();
|
||||
} else {
|
||||
this.valueFieldName = null;
|
||||
this.valueFieldDataType = null;
|
||||
this.script = context.scriptService().search(context.lookup(), scriptLang, script, params);
|
||||
this.aggregator = new ScriptAggregator(this.script);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,17 +82,17 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
|
|||
|
||||
@Override
|
||||
protected void doSetNextReader(AtomicReaderContext context) throws IOException {
|
||||
keyFieldData = fieldDataCache.cache(keyFieldDataType, context.reader(), keyFieldName);
|
||||
keyValues = keyIndexFieldData.load(context).getHashedBytesValues();
|
||||
if (script != null) {
|
||||
script.setNextReader(context);
|
||||
} else {
|
||||
aggregator.valueFieldData = (NumericFieldData) fieldDataCache.cache(valueFieldDataType, context.reader(), valueFieldName);
|
||||
aggregator.valueValues = valueIndexFieldData.load(context).getDoubleValues();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doCollect(int doc) throws IOException {
|
||||
keyFieldData.forEachValueInDoc(doc, aggregator);
|
||||
keyValues.forEachValueInDoc(doc, aggregator);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -155,27 +121,28 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
|
|||
return new InternalTermsStatsStringFacet(facetName, comparatorType, size, ordered, aggregator.missing);
|
||||
}
|
||||
|
||||
public static class Aggregator implements FieldData.StringValueInDocProc {
|
||||
public static class Aggregator implements HashedBytesValues.ValueInDocProc {
|
||||
|
||||
// LUCENE 4 UPGRADE: check if hashcode is not too expensive
|
||||
final ExtTHashMap<BytesRef, InternalTermsStatsStringFacet.StringEntry> entries = CacheRecycler.popHashMap();
|
||||
final ExtTHashMap<HashedBytesRef, InternalTermsStatsStringFacet.StringEntry> entries = CacheRecycler.popHashMap();
|
||||
|
||||
int missing = 0;
|
||||
|
||||
NumericFieldData valueFieldData;
|
||||
DoubleValues valueValues;
|
||||
|
||||
ValueAggregator valueAggregator = new ValueAggregator();
|
||||
|
||||
@Override
|
||||
public void onValue(int docId, BytesRef value) {
|
||||
public void onValue(int docId, HashedBytesRef value) {
|
||||
InternalTermsStatsStringFacet.StringEntry stringEntry = entries.get(value);
|
||||
if (stringEntry == null) {
|
||||
// we use "unsafe" hashedBytes, and only copy over if we "miss" on the map, and need to put it there
|
||||
value = value.deepCopy();
|
||||
stringEntry = new InternalTermsStatsStringFacet.StringEntry(value, 0, 0, 0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY);
|
||||
entries.put(value, stringEntry);
|
||||
}
|
||||
stringEntry.count++;
|
||||
valueAggregator.stringEntry = stringEntry;
|
||||
valueFieldData.forEachValueInDoc(docId, valueAggregator);
|
||||
valueValues.forEachValueInDoc(docId, valueAggregator);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -183,10 +150,14 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
|
|||
missing++;
|
||||
}
|
||||
|
||||
public static class ValueAggregator implements NumericFieldData.DoubleValueInDocProc {
|
||||
public static class ValueAggregator implements DoubleValues.ValueInDocProc {
|
||||
|
||||
InternalTermsStatsStringFacet.StringEntry stringEntry;
|
||||
|
||||
@Override
|
||||
public void onMissing(int docId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValue(int docId, double value) {
|
||||
if (value < stringEntry.min) {
|
||||
|
@ -209,9 +180,11 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onValue(int docId, BytesRef value) {
|
||||
public void onValue(int docId, HashedBytesRef value) {
|
||||
InternalTermsStatsStringFacet.StringEntry stringEntry = entries.get(value);
|
||||
if (stringEntry == null) {
|
||||
// we use "unsafe" hashedBytes, and only copy over if we "miss" on the map, and need to put it there
|
||||
value = value.deepCopy();
|
||||
stringEntry = new InternalTermsStatsStringFacet.StringEntry(value, 1, 0, 0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY);
|
||||
entries.put(value, stringEntry);
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue