"exclude" functionality missing for terms facet on numeric fields, closes #789.

This commit is contained in:
kimchy 2011-03-18 11:08:11 +02:00
parent 923fcf239c
commit 09fbc919b8
9 changed files with 139 additions and 33 deletions

View File

@ -39,7 +39,7 @@ public class TermsFacetBuilder extends AbstractFacetBuilder {
private String[] fieldsNames;
private int size = 10;
private Boolean allTerms;
private String[] exclude;
private Object[] exclude;
private String regex;
private int regexFlags = 0;
private TermsFacet.ComparatorType comparatorType;
@ -110,7 +110,7 @@ public class TermsFacetBuilder extends AbstractFacetBuilder {
/**
* A set of terms that will be excluded.
*/
public TermsFacetBuilder exclude(String... exclude) {
public TermsFacetBuilder exclude(Object... exclude) {
this.exclude = exclude;
return this;
}
@ -205,7 +205,7 @@ public class TermsFacetBuilder extends AbstractFacetBuilder {
builder.field("size", size);
if (exclude != null) {
builder.startArray("exclude");
for (String ex : exclude) {
for (Object ex : exclude) {
builder.value(ex);
}
builder.endArray();

View File

@ -144,17 +144,17 @@ public class TermsFacetProcessor extends AbstractComponent implements FacetProce
if (fieldMapper instanceof IpFieldMapper) {
return new TermsIpFacetCollector(facetName, field, size, comparatorType, allTerms, context, scriptLang, script, params);
} else if (fieldMapper.fieldDataType() == FieldDataType.DefaultTypes.LONG) {
return new TermsLongFacetCollector(facetName, field, size, comparatorType, allTerms, context, scriptLang, script, params);
return new TermsLongFacetCollector(facetName, field, size, comparatorType, allTerms, context, excluded, scriptLang, script, params);
} else if (fieldMapper.fieldDataType() == FieldDataType.DefaultTypes.DOUBLE) {
return new TermsDoubleFacetCollector(facetName, field, size, comparatorType, allTerms, context, scriptLang, script, params);
return new TermsDoubleFacetCollector(facetName, field, size, comparatorType, allTerms, context, excluded, scriptLang, script, params);
} else if (fieldMapper.fieldDataType() == FieldDataType.DefaultTypes.INT) {
return new TermsIntFacetCollector(facetName, field, size, comparatorType, allTerms, context, scriptLang, script, params);
return new TermsIntFacetCollector(facetName, field, size, comparatorType, allTerms, context, excluded, scriptLang, script, params);
} else if (fieldMapper.fieldDataType() == FieldDataType.DefaultTypes.FLOAT) {
return new TermsFloatFacetCollector(facetName, field, size, comparatorType, allTerms, context, scriptLang, script, params);
return new TermsFloatFacetCollector(facetName, field, size, comparatorType, allTerms, context, excluded, scriptLang, script, params);
} else if (fieldMapper.fieldDataType() == FieldDataType.DefaultTypes.SHORT) {
return new TermsShortFacetCollector(facetName, field, size, comparatorType, allTerms, context, scriptLang, script, params);
return new TermsShortFacetCollector(facetName, field, size, comparatorType, allTerms, context, excluded, scriptLang, script, params);
} else if (fieldMapper.fieldDataType() == FieldDataType.DefaultTypes.BYTE) {
return new TermsByteFacetCollector(facetName, field, size, comparatorType, allTerms, context, scriptLang, script, params);
return new TermsByteFacetCollector(facetName, field, size, comparatorType, allTerms, context, excluded, scriptLang, script, params);
}
}
return new TermsStringFacetCollector(facetName, field, size, comparatorType, allTerms, context, excluded, pattern, scriptLang, script, params);

View File

@ -24,9 +24,11 @@ import org.apache.lucene.search.Scorer;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.common.collect.BoundedTreeSet;
import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.collect.ImmutableSet;
import org.elasticsearch.common.thread.ThreadLocals;
import org.elasticsearch.common.trove.iterator.TByteIntIterator;
import org.elasticsearch.common.trove.map.hash.TByteIntHashMap;
import org.elasticsearch.common.trove.set.hash.TByteHashSet;
import org.elasticsearch.index.cache.field.data.FieldDataCache;
import org.elasticsearch.index.field.data.FieldDataType;
import org.elasticsearch.index.field.data.bytes.ByteFieldData;
@ -42,6 +44,7 @@ import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Map;
import java.util.Set;
/**
* @author kimchy (shay.banon)
@ -73,7 +76,7 @@ public class TermsByteFacetCollector extends AbstractFacetCollector {
private final SearchScript script;
public TermsByteFacetCollector(String facetName, String fieldName, int size, TermsFacet.ComparatorType comparatorType, boolean allTerms, SearchContext context,
String scriptLang, String script, Map<String, Object> params) {
ImmutableSet<String> excluded, String scriptLang, String script, Map<String, Object> params) {
super(facetName);
this.fieldDataCache = context.fieldDataCache();
this.size = size;
@ -103,10 +106,10 @@ public class TermsByteFacetCollector extends AbstractFacetCollector {
this.script = null;
}
if (this.script == null) {
if (this.script == null && excluded.isEmpty()) {
aggregator = new StaticAggregatorValueProc(popFacets());
} else {
aggregator = new AggregatorValueProc(popFacets(), this.script);
aggregator = new AggregatorValueProc(popFacets(), excluded, this.script);
}
if (allTerms) {
@ -177,12 +180,25 @@ public class TermsByteFacetCollector extends AbstractFacetCollector {
private final SearchScript script;
public AggregatorValueProc(TByteIntHashMap facets, SearchScript script) {
private final TByteHashSet excluded;
public AggregatorValueProc(TByteIntHashMap facets, Set<String> excluded, SearchScript script) {
super(facets);
if (excluded == null || excluded.isEmpty()) {
this.excluded = null;
} else {
this.excluded = new TByteHashSet(excluded.size());
for (String s : excluded) {
this.excluded.add(Byte.parseByte(s));
}
}
this.script = script;
}
@Override public void onValue(int docId, byte value) {
if (excluded != null && excluded.contains(value)) {
return;
}
if (script != null) {
script.setNextDocId(docId);
script.setNextVar("term", value);

View File

@ -24,9 +24,11 @@ import org.apache.lucene.search.Scorer;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.common.collect.BoundedTreeSet;
import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.collect.ImmutableSet;
import org.elasticsearch.common.thread.ThreadLocals;
import org.elasticsearch.common.trove.iterator.TDoubleIntIterator;
import org.elasticsearch.common.trove.map.hash.TDoubleIntHashMap;
import org.elasticsearch.common.trove.set.hash.TDoubleHashSet;
import org.elasticsearch.index.cache.field.data.FieldDataCache;
import org.elasticsearch.index.field.data.FieldDataType;
import org.elasticsearch.index.field.data.doubles.DoubleFieldData;
@ -42,6 +44,7 @@ import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Map;
import java.util.Set;
/**
* @author kimchy (shay.banon)
@ -73,7 +76,7 @@ public class TermsDoubleFacetCollector extends AbstractFacetCollector {
private final SearchScript script;
public TermsDoubleFacetCollector(String facetName, String fieldName, int size, TermsFacet.ComparatorType comparatorType, boolean allTerms, SearchContext context,
String scriptLang, String script, Map<String, Object> params) {
ImmutableSet<String> excluded, String scriptLang, String script, Map<String, Object> params) {
super(facetName);
this.fieldDataCache = context.fieldDataCache();
this.size = size;
@ -103,10 +106,10 @@ public class TermsDoubleFacetCollector extends AbstractFacetCollector {
this.script = null;
}
if (this.script == null) {
if (this.script == null && excluded.isEmpty()) {
aggregator = new StaticAggregatorValueProc(popFacets());
} else {
aggregator = new AggregatorValueProc(popFacets(), this.script);
aggregator = new AggregatorValueProc(popFacets(), excluded, this.script);
}
if (allTerms) {
@ -177,12 +180,25 @@ public class TermsDoubleFacetCollector extends AbstractFacetCollector {
private final SearchScript script;
public AggregatorValueProc(TDoubleIntHashMap facets, SearchScript script) {
private final TDoubleHashSet excluded;
public AggregatorValueProc(TDoubleIntHashMap facets, Set<String> excluded, SearchScript script) {
super(facets);
this.script = script;
if (excluded == null || excluded.isEmpty()) {
this.excluded = null;
} else {
this.excluded = new TDoubleHashSet(excluded.size());
for (String s : excluded) {
this.excluded.add(Double.parseDouble(s));
}
}
}
@Override public void onValue(int docId, double value) {
if (excluded != null && excluded.contains(value)) {
return;
}
if (script != null) {
script.setNextDocId(docId);
script.setNextVar("term", value);

View File

@ -24,9 +24,11 @@ import org.apache.lucene.search.Scorer;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.common.collect.BoundedTreeSet;
import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.collect.ImmutableSet;
import org.elasticsearch.common.thread.ThreadLocals;
import org.elasticsearch.common.trove.iterator.TFloatIntIterator;
import org.elasticsearch.common.trove.map.hash.TFloatIntHashMap;
import org.elasticsearch.common.trove.set.hash.TFloatHashSet;
import org.elasticsearch.index.cache.field.data.FieldDataCache;
import org.elasticsearch.index.field.data.FieldDataType;
import org.elasticsearch.index.field.data.floats.FloatFieldData;
@ -42,6 +44,7 @@ import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Map;
import java.util.Set;
/**
* @author kimchy (shay.banon)
@ -73,7 +76,7 @@ public class TermsFloatFacetCollector extends AbstractFacetCollector {
private final SearchScript script;
public TermsFloatFacetCollector(String facetName, String fieldName, int size, TermsFacet.ComparatorType comparatorType, boolean allTerms, SearchContext context,
String scriptLang, String script, Map<String, Object> params) {
ImmutableSet<String> excluded, String scriptLang, String script, Map<String, Object> params) {
super(facetName);
this.fieldDataCache = context.fieldDataCache();
this.size = size;
@ -103,10 +106,10 @@ public class TermsFloatFacetCollector extends AbstractFacetCollector {
this.script = null;
}
if (this.script == null) {
if (this.script == null && excluded.isEmpty()) {
aggregator = new StaticAggregatorValueProc(popFacets());
} else {
aggregator = new AggregatorValueProc(popFacets(), this.script);
aggregator = new AggregatorValueProc(popFacets(), excluded, this.script);
}
if (allTerms) {
@ -177,12 +180,25 @@ public class TermsFloatFacetCollector extends AbstractFacetCollector {
private final SearchScript script;
public AggregatorValueProc(TFloatIntHashMap facets, SearchScript script) {
private final TFloatHashSet excluded;
public AggregatorValueProc(TFloatIntHashMap facets, Set<String> excluded, SearchScript script) {
super(facets);
if (excluded == null || excluded.isEmpty()) {
this.excluded = null;
} else {
this.excluded = new TFloatHashSet(excluded.size());
for (String s : excluded) {
this.excluded.add(Float.parseFloat(s));
}
}
this.script = script;
}
@Override public void onValue(int docId, float value) {
if (excluded != null && excluded.contains(value)) {
return;
}
if (script != null) {
script.setNextDocId(docId);
script.setNextVar("term", value);

View File

@ -24,9 +24,11 @@ import org.apache.lucene.search.Scorer;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.common.collect.BoundedTreeSet;
import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.collect.ImmutableSet;
import org.elasticsearch.common.thread.ThreadLocals;
import org.elasticsearch.common.trove.iterator.TIntIntIterator;
import org.elasticsearch.common.trove.map.hash.TIntIntHashMap;
import org.elasticsearch.common.trove.set.hash.TIntHashSet;
import org.elasticsearch.index.cache.field.data.FieldDataCache;
import org.elasticsearch.index.field.data.FieldDataType;
import org.elasticsearch.index.field.data.ints.IntFieldData;
@ -42,6 +44,7 @@ import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Map;
import java.util.Set;
/**
* @author kimchy (shay.banon)
@ -73,7 +76,7 @@ public class TermsIntFacetCollector extends AbstractFacetCollector {
private final SearchScript script;
public TermsIntFacetCollector(String facetName, String fieldName, int size, TermsFacet.ComparatorType comparatorType, boolean allTerms, SearchContext context,
String scriptLang, String script, Map<String, Object> params) {
ImmutableSet<String> excluded, String scriptLang, String script, Map<String, Object> params) {
super(facetName);
this.fieldDataCache = context.fieldDataCache();
this.size = size;
@ -103,10 +106,10 @@ public class TermsIntFacetCollector extends AbstractFacetCollector {
this.script = null;
}
if (this.script == null) {
if (this.script == null && excluded.isEmpty()) {
aggregator = new StaticAggregatorValueProc(popFacets());
} else {
aggregator = new AggregatorValueProc(popFacets(), this.script);
aggregator = new AggregatorValueProc(popFacets(), excluded, this.script);
}
if (allTerms) {
@ -177,12 +180,25 @@ public class TermsIntFacetCollector extends AbstractFacetCollector {
private final SearchScript script;
public AggregatorValueProc(TIntIntHashMap facets, SearchScript script) {
private final TIntHashSet excluded;
public AggregatorValueProc(TIntIntHashMap facets, Set<String> excluded, SearchScript script) {
super(facets);
if (excluded == null || excluded.isEmpty()) {
this.excluded = null;
} else {
this.excluded = new TIntHashSet(excluded.size());
for (String s : excluded) {
this.excluded.add(Integer.parseInt(s));
}
}
this.script = script;
}
@Override public void onValue(int docId, int value) {
if (excluded != null && excluded.contains(value)) {
return;
}
if (script != null) {
script.setNextDocId(docId);
script.setNextVar("term", value);

View File

@ -24,9 +24,11 @@ import org.apache.lucene.search.Scorer;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.common.collect.BoundedTreeSet;
import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.collect.ImmutableSet;
import org.elasticsearch.common.thread.ThreadLocals;
import org.elasticsearch.common.trove.iterator.TLongIntIterator;
import org.elasticsearch.common.trove.map.hash.TLongIntHashMap;
import org.elasticsearch.common.trove.set.hash.TLongHashSet;
import org.elasticsearch.index.cache.field.data.FieldDataCache;
import org.elasticsearch.index.field.data.FieldDataType;
import org.elasticsearch.index.field.data.longs.LongFieldData;
@ -42,6 +44,7 @@ import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Map;
import java.util.Set;
/**
* @author kimchy (shay.banon)
@ -74,7 +77,7 @@ public class TermsLongFacetCollector extends AbstractFacetCollector {
private final SearchScript script;
public TermsLongFacetCollector(String facetName, String fieldName, int size, TermsFacet.ComparatorType comparatorType, boolean allTerms, SearchContext context,
String scriptLang, String script, Map<String, Object> params) {
ImmutableSet<String> excluded, String scriptLang, String script, Map<String, Object> params) {
super(facetName);
this.fieldDataCache = context.fieldDataCache();
this.size = size;
@ -104,10 +107,10 @@ public class TermsLongFacetCollector extends AbstractFacetCollector {
this.script = null;
}
if (this.script == null) {
if (this.script == null && excluded.isEmpty()) {
aggregator = new StaticAggregatorValueProc(popFacets());
} else {
aggregator = new AggregatorValueProc(popFacets(), this.script);
aggregator = new AggregatorValueProc(popFacets(), excluded, this.script);
}
if (allTerms) {
@ -178,12 +181,25 @@ public class TermsLongFacetCollector extends AbstractFacetCollector {
private final SearchScript script;
public AggregatorValueProc(TLongIntHashMap facets, SearchScript script) {
private final TLongHashSet excluded;
public AggregatorValueProc(TLongIntHashMap facets, Set<String> excluded, SearchScript script) {
super(facets);
this.script = script;
if (excluded == null || excluded.isEmpty()) {
this.excluded = null;
} else {
this.excluded = new TLongHashSet(excluded.size());
for (String s : excluded) {
this.excluded.add(Long.parseLong(s));
}
}
}
@Override public void onValue(int docId, long value) {
if (excluded != null && excluded.contains(value)) {
return;
}
if (script != null) {
script.setNextDocId(docId);
script.setNextVar("term", value);

View File

@ -24,9 +24,11 @@ import org.apache.lucene.search.Scorer;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.common.collect.BoundedTreeSet;
import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.collect.ImmutableSet;
import org.elasticsearch.common.thread.ThreadLocals;
import org.elasticsearch.common.trove.iterator.TShortIntIterator;
import org.elasticsearch.common.trove.map.hash.TShortIntHashMap;
import org.elasticsearch.common.trove.set.hash.TShortHashSet;
import org.elasticsearch.index.cache.field.data.FieldDataCache;
import org.elasticsearch.index.field.data.FieldDataType;
import org.elasticsearch.index.field.data.shorts.ShortFieldData;
@ -42,6 +44,7 @@ import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Map;
import java.util.Set;
/**
* @author kimchy (shay.banon)
@ -73,7 +76,7 @@ public class TermsShortFacetCollector extends AbstractFacetCollector {
private final SearchScript script;
public TermsShortFacetCollector(String facetName, String fieldName, int size, TermsFacet.ComparatorType comparatorType, boolean allTerms, SearchContext context,
String scriptLang, String script, Map<String, Object> params) {
ImmutableSet<String> excluded, String scriptLang, String script, Map<String, Object> params) {
super(facetName);
this.fieldDataCache = context.fieldDataCache();
this.size = size;
@ -103,10 +106,10 @@ public class TermsShortFacetCollector extends AbstractFacetCollector {
this.script = null;
}
if (this.script == null) {
if (this.script == null && excluded.isEmpty()) {
aggregator = new StaticAggregatorValueProc(popFacets());
} else {
aggregator = new AggregatorValueProc(popFacets(), this.script);
aggregator = new AggregatorValueProc(popFacets(), excluded, this.script);
}
if (allTerms) {
@ -177,12 +180,25 @@ public class TermsShortFacetCollector extends AbstractFacetCollector {
private final SearchScript script;
public AggregatorValueProc(TShortIntHashMap facets, SearchScript script) {
private final TShortHashSet excluded;
public AggregatorValueProc(TShortIntHashMap facets, Set<String> excluded, SearchScript script) {
super(facets);
if (excluded == null || excluded.isEmpty()) {
this.excluded = null;
} else {
this.excluded = new TShortHashSet(excluded.size());
for (String s : excluded) {
this.excluded.add(Short.parseShort(s));
}
}
this.script = script;
}
@Override public void onValue(int docId, short value) {
if (excluded != null && excluded.contains(value)) {
return;
}
if (script != null) {
script.setNextDocId(docId);
script.setNextVar("term", value);

View File

@ -432,6 +432,7 @@ public class SimpleFacetsTests extends AbstractNodesTests {
.setQuery(termQuery("stag", "111"))
.addFacet(termsFacet("facet1").field("lstag").size(10))
.addFacet(termsFacet("facet2").field("ltag").size(10))
.addFacet(termsFacet("facet3").field("ltag").size(10).exclude(3000))
.execute().actionGet();
facet = searchResponse.facets().facet("facet1");
@ -452,6 +453,15 @@ public class SimpleFacetsTests extends AbstractNodesTests {
assertThat(facet.entries().get(2).term(), anyOf(equalTo("1000"), equalTo("3000")));
assertThat(facet.entries().get(2).count(), equalTo(1));
facet = searchResponse.facets().facet("facet3");
assertThat(facet, instanceOf(InternalLongTermsFacet.class));
assertThat(facet.name(), equalTo("facet3"));
assertThat(facet.entries().size(), equalTo(2));
assertThat(facet.entries().get(0).term(), equalTo("2000"));
assertThat(facet.entries().get(0).count(), equalTo(2));
assertThat(facet.entries().get(1).term(), equalTo("1000"));
assertThat(facet.entries().get(1).count(), equalTo(1));
searchResponse = client.prepareSearch()
.setQuery(termQuery("stag", "111"))
.addFacet(termsFacet("facet1").field("dstag").size(10))