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() {
|
public String toString() {
|
||||||
return bytes.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> {
|
public interface IndexNumericFieldData<FD extends AtomicNumericFieldData> extends IndexFieldData<FD> {
|
||||||
|
|
||||||
static enum NumericType {
|
static enum NumericType {
|
||||||
BYTE,
|
BYTE {
|
||||||
SHORT,
|
@Override
|
||||||
INT,
|
public boolean isFloatingPoint() {
|
||||||
LONG,
|
return false;
|
||||||
FLOAT,
|
}
|
||||||
DOUBLE
|
},
|
||||||
|
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();
|
NumericType getNumericType();
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class LongArrayIndexFieldData extends AbstractIndexFieldData<LongArrayAto
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NumericType getNumericType() {
|
public NumericType getNumericType() {
|
||||||
return NumericType.DOUBLE;
|
return NumericType.LONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,8 +23,10 @@ import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
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.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.script.SearchScript;
|
||||||
import org.elasticsearch.search.facet.Facet;
|
import org.elasticsearch.search.facet.Facet;
|
||||||
import org.elasticsearch.search.facet.FacetCollector;
|
import org.elasticsearch.search.facet.FacetCollector;
|
||||||
import org.elasticsearch.search.facet.FacetPhaseExecutionException;
|
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");
|
throw new FacetPhaseExecutionException(facetName, "either [value_field] or [script] are required to be set for terms stats facet");
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldMapper keyFieldMapper = context.smartNameFieldMapper(keyField);
|
FieldMapper keyMapper = context.smartNameFieldMapper(keyField);
|
||||||
if (keyFieldMapper != null) {
|
if (keyMapper == null) {
|
||||||
if (keyFieldMapper.fieldDataType() == FieldDataType.DefaultTypes.LONG) {
|
throw new FacetPhaseExecutionException(facetName, "failed to find mapping for " + keyField);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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
|
@Override
|
||||||
|
|
|
@ -23,13 +23,10 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.apache.lucene.index.AtomicReaderContext;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.Scorer;
|
import org.apache.lucene.search.Scorer;
|
||||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
|
||||||
import org.elasticsearch.common.CacheRecycler;
|
import org.elasticsearch.common.CacheRecycler;
|
||||||
import org.elasticsearch.common.trove.ExtTDoubleObjectHashMap;
|
import org.elasticsearch.common.trove.ExtTDoubleObjectHashMap;
|
||||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
import org.elasticsearch.index.fielddata.DoubleValues;
|
||||||
import org.elasticsearch.index.field.data.FieldDataType;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
import org.elasticsearch.index.field.data.NumericFieldData;
|
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
|
||||||
import org.elasticsearch.script.SearchScript;
|
import org.elasticsearch.script.SearchScript;
|
||||||
import org.elasticsearch.search.facet.AbstractFacetCollector;
|
import org.elasticsearch.search.facet.AbstractFacetCollector;
|
||||||
import org.elasticsearch.search.facet.Facet;
|
import org.elasticsearch.search.facet.Facet;
|
||||||
|
@ -40,67 +37,35 @@ import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class TermsStatsDoubleFacetCollector extends AbstractFacetCollector {
|
public class TermsStatsDoubleFacetCollector extends AbstractFacetCollector {
|
||||||
|
|
||||||
private final TermsStatsFacet.ComparatorType comparatorType;
|
private final TermsStatsFacet.ComparatorType comparatorType;
|
||||||
|
|
||||||
private final FieldDataCache fieldDataCache;
|
private final IndexNumericFieldData keyIndexFieldData;
|
||||||
|
private final IndexNumericFieldData valueIndexFieldData;
|
||||||
private final String keyFieldName;
|
private final SearchScript script;
|
||||||
|
|
||||||
private final String valueFieldName;
|
|
||||||
|
|
||||||
private final int size;
|
private final int size;
|
||||||
|
|
||||||
private final int numberOfShards;
|
private final int numberOfShards;
|
||||||
|
|
||||||
private final FieldDataType keyFieldDataType;
|
|
||||||
|
|
||||||
private NumericFieldData keyFieldData;
|
|
||||||
|
|
||||||
private final FieldDataType valueFieldDataType;
|
|
||||||
|
|
||||||
private final SearchScript script;
|
|
||||||
|
|
||||||
private final Aggregator aggregator;
|
private final Aggregator aggregator;
|
||||||
|
|
||||||
public TermsStatsDoubleFacetCollector(String facetName, String keyFieldName, String valueFieldName, int size, TermsStatsFacet.ComparatorType comparatorType,
|
private DoubleValues keyValues;
|
||||||
SearchContext context, String scriptLang, String script, Map<String, Object> params) {
|
|
||||||
|
public TermsStatsDoubleFacetCollector(String facetName, IndexNumericFieldData keyIndexFieldData, IndexNumericFieldData valueIndexFieldData, SearchScript script,
|
||||||
|
int size, TermsStatsFacet.ComparatorType comparatorType, SearchContext context) {
|
||||||
super(facetName);
|
super(facetName);
|
||||||
this.fieldDataCache = context.fieldDataCache();
|
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.comparatorType = comparatorType;
|
this.comparatorType = comparatorType;
|
||||||
this.numberOfShards = context.numberOfShards();
|
this.numberOfShards = context.numberOfShards();
|
||||||
|
this.keyIndexFieldData = keyIndexFieldData;
|
||||||
MapperService.SmartNameFieldMappers smartMappers = context.smartFieldMappers(keyFieldName);
|
this.valueIndexFieldData = valueIndexFieldData;
|
||||||
if (smartMappers == null || !smartMappers.hasMapper()) {
|
this.script = script;
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (script == null) {
|
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();
|
this.aggregator = new Aggregator();
|
||||||
} else {
|
} else {
|
||||||
this.valueFieldName = null;
|
|
||||||
this.valueFieldDataType = null;
|
|
||||||
this.script = context.scriptService().search(context.lookup(), scriptLang, script, params);
|
|
||||||
this.aggregator = new ScriptAggregator(this.script);
|
this.aggregator = new ScriptAggregator(this.script);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,17 +79,17 @@ public class TermsStatsDoubleFacetCollector extends AbstractFacetCollector {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doSetNextReader(AtomicReaderContext context) throws IOException {
|
protected void doSetNextReader(AtomicReaderContext context) throws IOException {
|
||||||
keyFieldData = (NumericFieldData) fieldDataCache.cache(keyFieldDataType, context.reader(), keyFieldName);
|
keyValues = keyIndexFieldData.load(context).getDoubleValues();
|
||||||
if (script != null) {
|
if (script != null) {
|
||||||
script.setNextReader(context);
|
script.setNextReader(context);
|
||||||
} else {
|
} else {
|
||||||
aggregator.valueFieldData = (NumericFieldData) fieldDataCache.cache(valueFieldDataType, context.reader(), valueFieldName);
|
aggregator.valueFieldData = valueIndexFieldData.load(context).getDoubleValues();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doCollect(int doc) throws IOException {
|
protected void doCollect(int doc) throws IOException {
|
||||||
keyFieldData.forEachValueInDoc(doc, aggregator);
|
keyValues.forEachValueInDoc(doc, aggregator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -153,12 +118,12 @@ public class TermsStatsDoubleFacetCollector extends AbstractFacetCollector {
|
||||||
return new InternalTermsStatsDoubleFacet(facetName, comparatorType, size, ordered, aggregator.missing);
|
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();
|
final ExtTDoubleObjectHashMap<InternalTermsStatsDoubleFacet.DoubleEntry> entries = CacheRecycler.popDoubleObjectMap();
|
||||||
int missing;
|
int missing;
|
||||||
|
|
||||||
NumericFieldData valueFieldData;
|
DoubleValues valueFieldData;
|
||||||
|
|
||||||
final ValueAggregator valueAggregator = new ValueAggregator();
|
final ValueAggregator valueAggregator = new ValueAggregator();
|
||||||
|
|
||||||
|
@ -179,10 +144,14 @@ public class TermsStatsDoubleFacetCollector extends AbstractFacetCollector {
|
||||||
missing++;
|
missing++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ValueAggregator implements NumericFieldData.DoubleValueInDocProc {
|
public static class ValueAggregator implements DoubleValues.ValueInDocProc {
|
||||||
|
|
||||||
InternalTermsStatsDoubleFacet.DoubleEntry doubleEntry;
|
InternalTermsStatsDoubleFacet.DoubleEntry doubleEntry;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMissing(int docId) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onValue(int docId, double value) {
|
public void onValue(int docId, double value) {
|
||||||
if (value < doubleEntry.min) {
|
if (value < doubleEntry.min) {
|
||||||
|
|
|
@ -23,13 +23,11 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.apache.lucene.index.AtomicReaderContext;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.Scorer;
|
import org.apache.lucene.search.Scorer;
|
||||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
|
||||||
import org.elasticsearch.common.CacheRecycler;
|
import org.elasticsearch.common.CacheRecycler;
|
||||||
import org.elasticsearch.common.trove.ExtTLongObjectHashMap;
|
import org.elasticsearch.common.trove.ExtTLongObjectHashMap;
|
||||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
import org.elasticsearch.index.fielddata.DoubleValues;
|
||||||
import org.elasticsearch.index.field.data.FieldDataType;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
import org.elasticsearch.index.field.data.NumericFieldData;
|
import org.elasticsearch.index.fielddata.LongValues;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
|
||||||
import org.elasticsearch.script.SearchScript;
|
import org.elasticsearch.script.SearchScript;
|
||||||
import org.elasticsearch.search.facet.AbstractFacetCollector;
|
import org.elasticsearch.search.facet.AbstractFacetCollector;
|
||||||
import org.elasticsearch.search.facet.Facet;
|
import org.elasticsearch.search.facet.Facet;
|
||||||
|
@ -40,68 +38,35 @@ import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class TermsStatsLongFacetCollector extends AbstractFacetCollector {
|
public class TermsStatsLongFacetCollector extends AbstractFacetCollector {
|
||||||
|
|
||||||
private final TermsStatsFacet.ComparatorType comparatorType;
|
private final TermsStatsFacet.ComparatorType comparatorType;
|
||||||
|
|
||||||
private final FieldDataCache fieldDataCache;
|
private final IndexNumericFieldData keyIndexFieldData;
|
||||||
|
private final IndexNumericFieldData valueIndexFieldData;
|
||||||
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 SearchScript script;
|
private final SearchScript script;
|
||||||
|
|
||||||
|
private final int size;
|
||||||
|
private final int numberOfShards;
|
||||||
|
|
||||||
private final Aggregator aggregator;
|
private final Aggregator aggregator;
|
||||||
|
|
||||||
public TermsStatsLongFacetCollector(String facetName, String keyFieldName, String valueFieldName, int size, TermsStatsFacet.ComparatorType comparatorType,
|
private LongValues keyValues;
|
||||||
SearchContext context, String scriptLang, String script, Map<String, Object> params) {
|
|
||||||
|
public TermsStatsLongFacetCollector(String facetName, IndexNumericFieldData keyIndexFieldData, IndexNumericFieldData valueIndexFieldData, SearchScript script,
|
||||||
|
int size, TermsStatsFacet.ComparatorType comparatorType, SearchContext context) {
|
||||||
super(facetName);
|
super(facetName);
|
||||||
this.fieldDataCache = context.fieldDataCache();
|
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.comparatorType = comparatorType;
|
this.comparatorType = comparatorType;
|
||||||
this.numberOfShards = context.numberOfShards();
|
this.numberOfShards = context.numberOfShards();
|
||||||
|
this.keyIndexFieldData = keyIndexFieldData;
|
||||||
MapperService.SmartNameFieldMappers smartMappers = context.smartFieldMappers(keyFieldName);
|
this.valueIndexFieldData = valueIndexFieldData;
|
||||||
if (smartMappers == null || !smartMappers.hasMapper()) {
|
this.script = script;
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (script == null) {
|
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();
|
this.aggregator = new Aggregator();
|
||||||
} else {
|
} else {
|
||||||
this.valueFieldName = null;
|
|
||||||
this.valueFieldDataType = null;
|
|
||||||
this.script = context.scriptService().search(context.lookup(), scriptLang, script, params);
|
|
||||||
this.aggregator = new ScriptAggregator(this.script);
|
this.aggregator = new ScriptAggregator(this.script);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,17 +80,17 @@ public class TermsStatsLongFacetCollector extends AbstractFacetCollector {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doSetNextReader(AtomicReaderContext context) throws IOException {
|
protected void doSetNextReader(AtomicReaderContext context) throws IOException {
|
||||||
keyFieldData = (NumericFieldData) fieldDataCache.cache(keyFieldDataType, context.reader(), keyFieldName);
|
keyValues = keyIndexFieldData.load(context).getLongValues();
|
||||||
if (script != null) {
|
if (script != null) {
|
||||||
script.setNextReader(context);
|
script.setNextReader(context);
|
||||||
} else {
|
} else {
|
||||||
aggregator.valueFieldData = (NumericFieldData) fieldDataCache.cache(valueFieldDataType, context.reader(), valueFieldName);
|
aggregator.valueValues = valueIndexFieldData.load(context).getDoubleValues();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doCollect(int doc) throws IOException {
|
protected void doCollect(int doc) throws IOException {
|
||||||
keyFieldData.forEachValueInDoc(doc, aggregator);
|
keyValues.forEachValueInDoc(doc, aggregator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -155,13 +120,13 @@ public class TermsStatsLongFacetCollector extends AbstractFacetCollector {
|
||||||
return new InternalTermsStatsLongFacet(facetName, comparatorType, size, ordered, aggregator.missing);
|
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();
|
final ExtTLongObjectHashMap<InternalTermsStatsLongFacet.LongEntry> entries = CacheRecycler.popLongObjectMap();
|
||||||
|
|
||||||
int missing;
|
int missing;
|
||||||
|
|
||||||
NumericFieldData valueFieldData;
|
DoubleValues valueValues;
|
||||||
|
|
||||||
final ValueAggregator valueAggregator = new ValueAggregator();
|
final ValueAggregator valueAggregator = new ValueAggregator();
|
||||||
|
|
||||||
|
@ -174,7 +139,7 @@ public class TermsStatsLongFacetCollector extends AbstractFacetCollector {
|
||||||
}
|
}
|
||||||
longEntry.count++;
|
longEntry.count++;
|
||||||
valueAggregator.longEntry = longEntry;
|
valueAggregator.longEntry = longEntry;
|
||||||
valueFieldData.forEachValueInDoc(docId, valueAggregator);
|
valueValues.forEachValueInDoc(docId, valueAggregator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -182,10 +147,14 @@ public class TermsStatsLongFacetCollector extends AbstractFacetCollector {
|
||||||
missing++;
|
missing++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ValueAggregator implements NumericFieldData.DoubleValueInDocProc {
|
public static class ValueAggregator implements DoubleValues.ValueInDocProc {
|
||||||
|
|
||||||
InternalTermsStatsLongFacet.LongEntry longEntry;
|
InternalTermsStatsLongFacet.LongEntry longEntry;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMissing(int docId) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onValue(int docId, double value) {
|
public void onValue(int docId, double value) {
|
||||||
if (value < longEntry.min) {
|
if (value < longEntry.min) {
|
||||||
|
|
|
@ -20,12 +20,11 @@
|
||||||
package org.elasticsearch.search.facet.termsstats.strings;
|
package org.elasticsearch.search.facet.termsstats.strings;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import org.apache.lucene.util.BytesRef;
|
|
||||||
import org.elasticsearch.common.CacheRecycler;
|
import org.elasticsearch.common.CacheRecycler;
|
||||||
import org.elasticsearch.common.bytes.BytesArray;
|
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.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
import org.elasticsearch.common.lucene.HashedBytesRef;
|
||||||
import org.elasticsearch.common.text.BytesText;
|
import org.elasticsearch.common.text.BytesText;
|
||||||
import org.elasticsearch.common.text.Text;
|
import org.elasticsearch.common.text.Text;
|
||||||
import org.elasticsearch.common.trove.ExtTHashMap;
|
import org.elasticsearch.common.trove.ExtTHashMap;
|
||||||
|
@ -69,8 +68,8 @@ public class InternalTermsStatsStringFacet extends InternalTermsStatsFacet {
|
||||||
double min;
|
double min;
|
||||||
double max;
|
double max;
|
||||||
|
|
||||||
public StringEntry(BytesRef term, long count, long totalCount, double total, double min, double max) {
|
public StringEntry(HashedBytesRef term, long count, long totalCount, double total, double min, double max) {
|
||||||
this(new BytesText(new BytesArray(term)), count, totalCount, total, min, 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) {
|
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 com.google.common.collect.Lists;
|
||||||
import org.apache.lucene.index.AtomicReaderContext;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.Scorer;
|
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.CacheRecycler;
|
||||||
|
import org.elasticsearch.common.lucene.HashedBytesRef;
|
||||||
import org.elasticsearch.common.trove.ExtTHashMap;
|
import org.elasticsearch.common.trove.ExtTHashMap;
|
||||||
import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
import org.elasticsearch.index.fielddata.DoubleValues;
|
||||||
import org.elasticsearch.index.field.data.FieldData;
|
import org.elasticsearch.index.fielddata.HashedBytesValues;
|
||||||
import org.elasticsearch.index.field.data.FieldDataType;
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
import org.elasticsearch.index.field.data.NumericFieldData;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
|
||||||
import org.elasticsearch.script.SearchScript;
|
import org.elasticsearch.script.SearchScript;
|
||||||
import org.elasticsearch.search.facet.AbstractFacetCollector;
|
import org.elasticsearch.search.facet.AbstractFacetCollector;
|
||||||
import org.elasticsearch.search.facet.Facet;
|
import org.elasticsearch.search.facet.Facet;
|
||||||
|
@ -42,68 +40,36 @@ import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
|
public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
|
||||||
|
|
||||||
private final TermsStatsFacet.ComparatorType comparatorType;
|
private final TermsStatsFacet.ComparatorType comparatorType;
|
||||||
|
|
||||||
private final FieldDataCache fieldDataCache;
|
private final IndexFieldData keyIndexFieldData;
|
||||||
|
private final IndexNumericFieldData valueIndexFieldData;
|
||||||
private final String keyFieldName;
|
private final SearchScript script;
|
||||||
|
|
||||||
private final String valueFieldName;
|
|
||||||
|
|
||||||
private final int size;
|
private final int size;
|
||||||
|
|
||||||
private final int numberOfShards;
|
private final int numberOfShards;
|
||||||
|
|
||||||
private final FieldDataType keyFieldDataType;
|
|
||||||
|
|
||||||
private FieldData keyFieldData;
|
|
||||||
|
|
||||||
private final FieldDataType valueFieldDataType;
|
|
||||||
|
|
||||||
private final SearchScript script;
|
|
||||||
|
|
||||||
private final Aggregator aggregator;
|
private final Aggregator aggregator;
|
||||||
|
|
||||||
public TermsStatsStringFacetCollector(String facetName, String keyFieldName, String valueFieldName, int size, TermsStatsFacet.ComparatorType comparatorType,
|
private HashedBytesValues keyValues;
|
||||||
SearchContext context, String scriptLang, String script, Map<String, Object> params) {
|
|
||||||
|
public TermsStatsStringFacetCollector(String facetName, IndexFieldData keyIndexFieldData, IndexNumericFieldData valueIndexFieldData, SearchScript valueScript,
|
||||||
|
int size, TermsStatsFacet.ComparatorType comparatorType, SearchContext context) {
|
||||||
super(facetName);
|
super(facetName);
|
||||||
this.fieldDataCache = context.fieldDataCache();
|
this.keyIndexFieldData = keyIndexFieldData;
|
||||||
|
this.valueIndexFieldData = valueIndexFieldData;
|
||||||
|
this.script = valueScript;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.comparatorType = comparatorType;
|
this.comparatorType = comparatorType;
|
||||||
this.numberOfShards = context.numberOfShards();
|
this.numberOfShards = context.numberOfShards();
|
||||||
|
|
||||||
MapperService.SmartNameFieldMappers smartMappers = context.smartFieldMappers(keyFieldName);
|
if (script != null) {
|
||||||
if (smartMappers == null || !smartMappers.hasMapper()) {
|
this.aggregator = new ScriptAggregator(valueScript);
|
||||||
this.keyFieldName = keyFieldName;
|
|
||||||
this.keyFieldDataType = FieldDataType.DefaultTypes.STRING;
|
|
||||||
} else {
|
} 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();
|
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
|
@Override
|
||||||
protected void doSetNextReader(AtomicReaderContext context) throws IOException {
|
protected void doSetNextReader(AtomicReaderContext context) throws IOException {
|
||||||
keyFieldData = fieldDataCache.cache(keyFieldDataType, context.reader(), keyFieldName);
|
keyValues = keyIndexFieldData.load(context).getHashedBytesValues();
|
||||||
if (script != null) {
|
if (script != null) {
|
||||||
script.setNextReader(context);
|
script.setNextReader(context);
|
||||||
} else {
|
} else {
|
||||||
aggregator.valueFieldData = (NumericFieldData) fieldDataCache.cache(valueFieldDataType, context.reader(), valueFieldName);
|
aggregator.valueValues = valueIndexFieldData.load(context).getDoubleValues();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doCollect(int doc) throws IOException {
|
protected void doCollect(int doc) throws IOException {
|
||||||
keyFieldData.forEachValueInDoc(doc, aggregator);
|
keyValues.forEachValueInDoc(doc, aggregator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -155,27 +121,28 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
|
||||||
return new InternalTermsStatsStringFacet(facetName, comparatorType, size, ordered, aggregator.missing);
|
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<HashedBytesRef, InternalTermsStatsStringFacet.StringEntry> entries = CacheRecycler.popHashMap();
|
||||||
final ExtTHashMap<BytesRef, InternalTermsStatsStringFacet.StringEntry> entries = CacheRecycler.popHashMap();
|
|
||||||
|
|
||||||
int missing = 0;
|
int missing = 0;
|
||||||
|
|
||||||
NumericFieldData valueFieldData;
|
DoubleValues valueValues;
|
||||||
|
|
||||||
ValueAggregator valueAggregator = new ValueAggregator();
|
ValueAggregator valueAggregator = new ValueAggregator();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onValue(int docId, BytesRef value) {
|
public void onValue(int docId, HashedBytesRef value) {
|
||||||
InternalTermsStatsStringFacet.StringEntry stringEntry = entries.get(value);
|
InternalTermsStatsStringFacet.StringEntry stringEntry = entries.get(value);
|
||||||
if (stringEntry == null) {
|
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);
|
stringEntry = new InternalTermsStatsStringFacet.StringEntry(value, 0, 0, 0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY);
|
||||||
entries.put(value, stringEntry);
|
entries.put(value, stringEntry);
|
||||||
}
|
}
|
||||||
stringEntry.count++;
|
stringEntry.count++;
|
||||||
valueAggregator.stringEntry = stringEntry;
|
valueAggregator.stringEntry = stringEntry;
|
||||||
valueFieldData.forEachValueInDoc(docId, valueAggregator);
|
valueValues.forEachValueInDoc(docId, valueAggregator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -183,10 +150,14 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
|
||||||
missing++;
|
missing++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ValueAggregator implements NumericFieldData.DoubleValueInDocProc {
|
public static class ValueAggregator implements DoubleValues.ValueInDocProc {
|
||||||
|
|
||||||
InternalTermsStatsStringFacet.StringEntry stringEntry;
|
InternalTermsStatsStringFacet.StringEntry stringEntry;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMissing(int docId) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onValue(int docId, double value) {
|
public void onValue(int docId, double value) {
|
||||||
if (value < stringEntry.min) {
|
if (value < stringEntry.min) {
|
||||||
|
@ -209,9 +180,11 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onValue(int docId, BytesRef value) {
|
public void onValue(int docId, HashedBytesRef value) {
|
||||||
InternalTermsStatsStringFacet.StringEntry stringEntry = entries.get(value);
|
InternalTermsStatsStringFacet.StringEntry stringEntry = entries.get(value);
|
||||||
if (stringEntry == null) {
|
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);
|
stringEntry = new InternalTermsStatsStringFacet.StringEntry(value, 1, 0, 0, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY);
|
||||||
entries.put(value, stringEntry);
|
entries.put(value, stringEntry);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue