Search Facets: Facets to allow to define filters on them, closes #217.

This commit is contained in:
kimchy 2010-06-08 22:30:21 +03:00
parent 6257b78243
commit 5ca050ffcb
13 changed files with 256 additions and 37 deletions

View File

@ -28,6 +28,7 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.support.PlainListenableActionFuture;
import org.elasticsearch.client.internal.InternalClient;
import org.elasticsearch.index.query.xcontent.XContentFilterBuilder;
import org.elasticsearch.index.query.xcontent.XContentQueryBuilder;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.builder.SearchSourceBuilder;
@ -36,6 +37,8 @@ import org.elasticsearch.search.builder.SearchSourceHighlightBuilder;
import org.elasticsearch.search.facets.histogram.HistogramFacet;
import org.elasticsearch.util.TimeValue;
import javax.annotation.Nullable;
/**
* A search action request builder.
*
@ -261,6 +264,11 @@ public class SearchRequestBuilder {
return this;
}
public SearchRequestBuilder addFacetQuery(String name, XContentQueryBuilder query, @Nullable XContentFilterBuilder filter) {
facetsBuilder().queryFacet(name, query, filter);
return this;
}
/**
* Adds a query facet (which results in a count facet returned) with an option to
* be global on the index or bounded by the search query.
@ -274,6 +282,11 @@ public class SearchRequestBuilder {
return this;
}
public SearchRequestBuilder addFacetGlobalQuery(String name, XContentQueryBuilder query, @Nullable XContentFilterBuilder filter) {
facetsBuilder().queryFacetGlobal(name, query, filter);
return this;
}
/**
* Adds a term facet for the provided field name.
*
@ -287,6 +300,11 @@ public class SearchRequestBuilder {
return this;
}
public SearchRequestBuilder addFacetTerms(String name, String fieldName, int size, @Nullable XContentFilterBuilder filter) {
facetsBuilder().termsFacet(name, fieldName, size, filter);
return this;
}
/**
* Adds a <b>global</b> term facet for the provided field name.
*
@ -300,6 +318,11 @@ public class SearchRequestBuilder {
return this;
}
public SearchRequestBuilder addFacetGlobalTerms(String name, String fieldName, int size, @Nullable XContentFilterBuilder filter) {
facetsBuilder().termsFacetGlobal(name, fieldName, size, filter);
return this;
}
/**
* Adds a numeric statistical facet for the provided field name.
*
@ -312,6 +335,11 @@ public class SearchRequestBuilder {
return this;
}
public SearchRequestBuilder addFacetStatistical(String name, String fieldName, @Nullable XContentFilterBuilder filter) {
facetsBuilder().statisticalFacet(name, fieldName, filter);
return this;
}
/**
* Adds a numeric statistical <b>global</b> facet for the provided field name.
*
@ -324,26 +352,53 @@ public class SearchRequestBuilder {
return this;
}
public SearchRequestBuilder addFacetGlobalStatistical(String name, String fieldName, @Nullable XContentFilterBuilder filter) {
facetsBuilder().statisticalFacetGlobal(name, fieldName, filter);
return this;
}
public SearchRequestBuilder addFacetHistogram(String name, String fieldName, long interval) {
facetsBuilder().histogramFacet(name, fieldName, interval);
return this;
}
public SearchRequestBuilder addFacetHistogram(String name, String fieldName, long interval, @Nullable XContentFilterBuilder filter) {
facetsBuilder().histogramFacet(name, fieldName, interval, filter);
return this;
}
public SearchRequestBuilder addFacetHistogram(String name, String fieldName, long interval, HistogramFacet.ComparatorType comparatorType) {
facetsBuilder().histogramFacet(name, fieldName, interval, comparatorType);
return this;
}
public SearchRequestBuilder addFacetHistogram(String name, String fieldName, long interval, HistogramFacet.ComparatorType comparatorType,
@Nullable XContentFilterBuilder filter) {
facetsBuilder().histogramFacet(name, fieldName, interval, comparatorType, filter);
return this;
}
public SearchRequestBuilder addFacetHistogramGlobal(String name, String fieldName, long interval) {
facetsBuilder().histogramFacetGlobal(name, fieldName, interval);
return this;
}
public SearchRequestBuilder addFacetHistogramGlobal(String name, String fieldName, long interval, @Nullable XContentFilterBuilder filter) {
facetsBuilder().histogramFacetGlobal(name, fieldName, interval, filter);
return this;
}
public SearchRequestBuilder addFacetHistogramGlobal(String name, String fieldName, long interval, HistogramFacet.ComparatorType comparatorType) {
facetsBuilder().histogramFacetGlobal(name, fieldName, interval, comparatorType);
return this;
}
public SearchRequestBuilder addFacetHistogramGlobal(String name, String fieldName, long interval, HistogramFacet.ComparatorType comparatorType,
@Nullable XContentFilterBuilder filter) {
facetsBuilder().histogramFacetGlobal(name, fieldName, interval, comparatorType, filter);
return this;
}
/**
* Adds a field to be highlighted with default fragment size of 100 characters, and
* default number of fragments of 5.

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index.query.xcontent;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Query;
import org.elasticsearch.ElasticSearchException;
import org.elasticsearch.index.AbstractIndexComponent;
@ -190,6 +191,18 @@ public class XContentIndexQueryParser extends AbstractIndexComponent implements
}
}
public Filter parseInnerFilter(XContentParser parser) throws IOException {
QueryParseContext context = cache.get().get();
context.reset(parser);
return context.parseInnerFilter();
}
public Query parseInnerQuery(XContentParser parser) throws IOException {
QueryParseContext context = cache.get().get();
context.reset(parser);
return context.parseInnerQuery();
}
private Query parse(QueryParseContext parseContext, XContentParser parser) throws IOException, QueryParsingException {
parseContext.reset(parser);
return parseContext.parseInnerQuery();

View File

@ -19,6 +19,7 @@
package org.elasticsearch.search.builder;
import org.elasticsearch.index.query.xcontent.XContentFilterBuilder;
import org.elasticsearch.index.query.xcontent.XContentQueryBuilder;
import org.elasticsearch.search.facets.histogram.HistogramFacet;
import org.elasticsearch.search.facets.histogram.HistogramFacetCollectorParser;
@ -28,6 +29,7 @@ import org.elasticsearch.search.facets.terms.TermsFacetCollectorParser;
import org.elasticsearch.util.xcontent.ToXContent;
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.List;
@ -46,20 +48,28 @@ public class SearchSourceFacetsBuilder implements ToXContent {
private List<BuilderStatisticalFacet> statisticalFacets;
private List<BuilderHistogramFacet> histogramFacets;
public SearchSourceFacetsBuilder queryFacet(String name, XContentQueryBuilder query) {
return queryFacet(name, query, null);
}
/**
* Adds a query facet (which results in a count facet returned).
*
* @param name The logical name of the facet, it will be returned under the name
* @param query The query facet
*/
public SearchSourceFacetsBuilder queryFacet(String name, XContentQueryBuilder query) {
public SearchSourceFacetsBuilder queryFacet(String name, XContentQueryBuilder query, @Nullable XContentFilterBuilder filter) {
if (queryFacets == null) {
queryFacets = newArrayListWithCapacity(2);
}
queryFacets.add(new BuilderQueryFacet(name, query, false));
queryFacets.add(new BuilderQueryFacet(name, query, filter, false));
return this;
}
public SearchSourceFacetsBuilder queryFacetGlobal(String name, XContentQueryBuilder query) {
return queryFacetGlobal(name, query, null);
}
/**
* Adds a query facet (which results in a count facet returned) with an option to
* be global on the index or bounded by the search query.
@ -67,67 +77,101 @@ public class SearchSourceFacetsBuilder implements ToXContent {
* @param name The logical name of the facet, it will be returned under the name
* @param query The query facet
*/
public SearchSourceFacetsBuilder queryFacetGlobal(String name, XContentQueryBuilder query) {
public SearchSourceFacetsBuilder queryFacetGlobal(String name, XContentQueryBuilder query, @Nullable XContentFilterBuilder filter) {
if (queryFacets == null) {
queryFacets = newArrayListWithCapacity(2);
}
queryFacets.add(new BuilderQueryFacet(name, query, true));
queryFacets.add(new BuilderQueryFacet(name, query, filter, true));
return this;
}
public SearchSourceFacetsBuilder termsFacet(String name, String fieldName, int size) {
return termsFacet(name, fieldName, size, null);
}
public SearchSourceFacetsBuilder termsFacet(String name, String fieldName, int size, @Nullable XContentFilterBuilder filter) {
if (termsFacets == null) {
termsFacets = newArrayListWithCapacity(2);
}
termsFacets.add(new BuilderTermsFacet(name, fieldName, size, false));
termsFacets.add(new BuilderTermsFacet(name, fieldName, size, filter, false));
return this;
}
public SearchSourceFacetsBuilder termsFacetGlobal(String name, String fieldName, int size) {
return termsFacetGlobal(name, fieldName, size, null);
}
public SearchSourceFacetsBuilder termsFacetGlobal(String name, String fieldName, int size, @Nullable XContentFilterBuilder filter) {
if (termsFacets == null) {
termsFacets = newArrayListWithCapacity(2);
}
termsFacets.add(new BuilderTermsFacet(name, fieldName, size, true));
termsFacets.add(new BuilderTermsFacet(name, fieldName, size, filter, true));
return this;
}
public SearchSourceFacetsBuilder statisticalFacet(String name, String fieldName) {
return statisticalFacet(name, fieldName, null);
}
public SearchSourceFacetsBuilder statisticalFacet(String name, String fieldName, @Nullable XContentFilterBuilder filter) {
if (statisticalFacets == null) {
statisticalFacets = newArrayListWithCapacity(2);
}
statisticalFacets.add(new BuilderStatisticalFacet(name, fieldName, false));
statisticalFacets.add(new BuilderStatisticalFacet(name, fieldName, filter, false));
return this;
}
public SearchSourceFacetsBuilder statisticalFacetGlobal(String name, String fieldName) {
return statisticalFacetGlobal(name, fieldName, null);
}
public SearchSourceFacetsBuilder statisticalFacetGlobal(String name, String fieldName, @Nullable XContentFilterBuilder filter) {
if (statisticalFacets == null) {
statisticalFacets = newArrayListWithCapacity(2);
}
statisticalFacets.add(new BuilderStatisticalFacet(name, fieldName, true));
statisticalFacets.add(new BuilderStatisticalFacet(name, fieldName, filter, true));
return this;
}
public SearchSourceFacetsBuilder histogramFacet(String name, String fieldName, long interval) {
return histogramFacet(name, fieldName, interval, HistogramFacet.ComparatorType.VALUE);
return histogramFacet(name, fieldName, interval, HistogramFacet.ComparatorType.VALUE, null);
}
public SearchSourceFacetsBuilder histogramFacet(String name, String fieldName, long interval, @Nullable XContentFilterBuilder filter) {
return histogramFacet(name, fieldName, interval, HistogramFacet.ComparatorType.VALUE, filter);
}
public SearchSourceFacetsBuilder histogramFacet(String name, String fieldName, long interval, HistogramFacet.ComparatorType comparatorType) {
return histogramFacet(name, fieldName, interval, comparatorType, null);
}
public SearchSourceFacetsBuilder histogramFacet(String name, String fieldName, long interval, HistogramFacet.ComparatorType comparatorType,
@Nullable XContentFilterBuilder filter) {
if (histogramFacets == null) {
histogramFacets = newArrayListWithCapacity(2);
}
histogramFacets.add(new BuilderHistogramFacet(name, fieldName, interval, comparatorType, false));
histogramFacets.add(new BuilderHistogramFacet(name, fieldName, interval, comparatorType, filter, false));
return this;
}
public SearchSourceFacetsBuilder histogramFacetGlobal(String name, String fieldName, long interval) {
return histogramFacet(name, fieldName, interval, HistogramFacet.ComparatorType.VALUE);
return histogramFacet(name, fieldName, interval, HistogramFacet.ComparatorType.VALUE, null);
}
public SearchSourceFacetsBuilder histogramFacetGlobal(String name, String fieldName, long interval, @Nullable XContentFilterBuilder filter) {
return histogramFacet(name, fieldName, interval, HistogramFacet.ComparatorType.VALUE, filter);
}
public SearchSourceFacetsBuilder histogramFacetGlobal(String name, String fieldName, long interval, HistogramFacet.ComparatorType comparatorType) {
return histogramFacetGlobal(name, fieldName, interval, comparatorType, null);
}
public SearchSourceFacetsBuilder histogramFacetGlobal(String name, String fieldName, long interval, HistogramFacet.ComparatorType comparatorType,
@Nullable XContentFilterBuilder filter) {
if (histogramFacets == null) {
histogramFacets = newArrayListWithCapacity(2);
}
histogramFacets.add(new BuilderHistogramFacet(name, fieldName, interval, comparatorType, true));
histogramFacets.add(new BuilderHistogramFacet(name, fieldName, interval, comparatorType, filter, true));
return this;
}
@ -144,6 +188,12 @@ public class SearchSourceFacetsBuilder implements ToXContent {
builder.startObject(queryFacet.name());
builder.field(QueryFacetCollectorParser.NAME);
queryFacet.queryBuilder().toXContent(builder, params);
if (queryFacet.filter() != null) {
builder.field("filter");
queryFacet.filter().toXContent(builder, params);
}
if (queryFacet.global() != null) {
builder.field("global", queryFacet.global());
}
@ -159,6 +209,10 @@ public class SearchSourceFacetsBuilder implements ToXContent {
builder.field("size", termsFacet.size());
builder.endObject();
if (termsFacet.filter() != null) {
builder.field("filter");
termsFacet.filter().toXContent(builder, params);
}
if (termsFacet.global() != null) {
builder.field("global", termsFacet.global());
}
@ -175,6 +229,11 @@ public class SearchSourceFacetsBuilder implements ToXContent {
builder.field("field", statisticalFacet.fieldName());
builder.endObject();
if (statisticalFacet.filter() != null) {
builder.field("filter");
statisticalFacet.filter().toXContent(builder, params);
}
if (statisticalFacet.global() != null) {
builder.field("global", statisticalFacet.global());
}
@ -193,6 +252,11 @@ public class SearchSourceFacetsBuilder implements ToXContent {
builder.field("comparator", histogramFacet.comparatorType().description());
builder.endObject();
if (histogramFacet.filter() != null) {
builder.field("filter");
histogramFacet.filter().toXContent(builder, params);
}
if (histogramFacet.global() != null) {
builder.field("global", histogramFacet.global());
}
@ -209,11 +273,13 @@ public class SearchSourceFacetsBuilder implements ToXContent {
private final String fieldName;
private final int size;
private final Boolean global;
private final XContentFilterBuilder filter;
private BuilderTermsFacet(String name, String fieldName, int size, Boolean global) {
private BuilderTermsFacet(String name, String fieldName, int size, XContentFilterBuilder filter, Boolean global) {
this.name = name;
this.fieldName = fieldName;
this.size = size;
this.filter = filter;
this.global = global;
}
@ -229,6 +295,10 @@ public class SearchSourceFacetsBuilder implements ToXContent {
return size;
}
public XContentFilterBuilder filter() {
return filter;
}
public Boolean global() {
return global;
}
@ -237,11 +307,13 @@ public class SearchSourceFacetsBuilder implements ToXContent {
private static class BuilderQueryFacet {
private final String name;
private final XContentQueryBuilder queryBuilder;
private final XContentFilterBuilder filter;
private final Boolean global;
private BuilderQueryFacet(String name, XContentQueryBuilder queryBuilder, Boolean global) {
private BuilderQueryFacet(String name, XContentQueryBuilder queryBuilder, XContentFilterBuilder filter, Boolean global) {
this.name = name;
this.queryBuilder = queryBuilder;
this.filter = filter;
this.global = global;
}
@ -253,6 +325,10 @@ public class SearchSourceFacetsBuilder implements ToXContent {
return queryBuilder;
}
public XContentFilterBuilder filter() {
return filter;
}
public Boolean global() {
return this.global;
}
@ -261,11 +337,13 @@ public class SearchSourceFacetsBuilder implements ToXContent {
private static class BuilderStatisticalFacet {
private final String name;
private final String fieldName;
private final XContentFilterBuilder filter;
private final Boolean global;
private BuilderStatisticalFacet(String name, String fieldName, Boolean global) {
private BuilderStatisticalFacet(String name, String fieldName, XContentFilterBuilder filter, Boolean global) {
this.name = name;
this.fieldName = fieldName;
this.filter = filter;
this.global = global;
}
@ -277,6 +355,10 @@ public class SearchSourceFacetsBuilder implements ToXContent {
return fieldName;
}
public XContentFilterBuilder filter() {
return this.filter;
}
public Boolean global() {
return this.global;
}
@ -287,17 +369,20 @@ public class SearchSourceFacetsBuilder implements ToXContent {
private final String fieldName;
private final long interval;
private final HistogramFacet.ComparatorType comparatorType;
private final XContentFilterBuilder filter;
private final Boolean global;
private BuilderHistogramFacet(String name, String fieldName, long interval, Boolean global) {
this(name, fieldName, interval, HistogramFacet.ComparatorType.VALUE, global);
private BuilderHistogramFacet(String name, String fieldName, long interval, XContentFilterBuilder filter, Boolean global) {
this(name, fieldName, interval, HistogramFacet.ComparatorType.VALUE, filter, global);
}
private BuilderHistogramFacet(String name, String fieldName, long interval, HistogramFacet.ComparatorType comparatorType, Boolean global) {
private BuilderHistogramFacet(String name, String fieldName, long interval, HistogramFacet.ComparatorType comparatorType,
XContentFilterBuilder filter, Boolean global) {
this.name = name;
this.fieldName = fieldName;
this.interval = interval;
this.comparatorType = comparatorType;
this.filter = filter;
this.global = global;
}
@ -317,6 +402,10 @@ public class SearchSourceFacetsBuilder implements ToXContent {
return this.comparatorType;
}
public XContentFilterBuilder filter() {
return this.filter;
}
public Boolean global() {
return this.global;
}

View File

@ -19,6 +19,8 @@
package org.elasticsearch.search.facets;
import org.apache.lucene.search.Filter;
import org.elasticsearch.index.query.xcontent.XContentIndexQueryParser;
import org.elasticsearch.search.SearchParseElement;
import org.elasticsearch.search.SearchParseException;
import org.elasticsearch.search.facets.collector.FacetCollector;
@ -82,21 +84,36 @@ public class FacetsParseElement implements SearchParseElement {
FacetCollector facet = null;
boolean global = false;
String facetFieldName = null;
Filter filter = null;
boolean cacheFilter = true;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
facetFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
FacetCollectorParser facetCollectorParser = facetCollectorParsers.get(facetFieldName);
if (facetCollectorParser == null) {
throw new SearchParseException(context, "No facet type for [" + facetFieldName + "]");
if ("filter".equals(facetFieldName)) {
XContentIndexQueryParser indexQueryParser = (XContentIndexQueryParser) context.queryParser();
filter = indexQueryParser.parseInnerFilter(parser);
} else {
FacetCollectorParser facetCollectorParser = facetCollectorParsers.get(facetFieldName);
if (facetCollectorParser == null) {
throw new SearchParseException(context, "No facet type for [" + facetFieldName + "]");
}
facet = facetCollectorParser.parser(topLevelFieldName, parser, context);
}
facet = facetCollectorParser.parser(topLevelFieldName, parser, context);
} else if (token.isValue()) {
if ("global".equals(facetFieldName)) {
global = parser.booleanValue();
} else if ("cache_filter".equals(facetFieldName) || "cacheFilter".equals(facetFieldName)) {
cacheFilter = parser.booleanValue();
}
}
}
if (filter != null) {
if (cacheFilter) {
filter = context.filterCache().cache(filter);
}
facet.setFilter(filter);
}
if (facetCollectors == null) {
facetCollectors = Lists.newArrayList();

View File

@ -20,6 +20,7 @@
package org.elasticsearch.search.facets.collector;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.Filter;
import org.elasticsearch.search.facets.Facet;
/**
@ -28,4 +29,6 @@ import org.elasticsearch.search.facets.Facet;
public abstract class FacetCollector extends Collector {
public abstract Facet facet();
public abstract void setFilter(Filter filter);
}

View File

@ -70,11 +70,11 @@ public class HistogramFacetCollector extends AbstractFacetCollector {
histoProc = new HistogramProc(interval);
}
@Override public void collect(int doc) throws IOException {
@Override protected void doCollect(int doc) throws IOException {
fieldData.forEachValueInDoc(doc, histoProc);
}
@Override public void setNextReader(IndexReader reader, int docBase) throws IOException {
@Override protected void doSetNextReader(IndexReader reader, int docBase) throws IOException {
fieldData = (NumericFieldData) fieldDataCache.cache(fieldDataType, reader, fieldName, fieldDataOptions().withFreqs(false));
}

View File

@ -42,9 +42,9 @@ public class HistogramFacetCollectorParser implements FacetCollectorParser {
String field = null;
String fieldName = null;
XContentParser.Token token;
long interval = -1;
HistogramFacet.ComparatorType comparatorType = HistogramFacet.ComparatorType.VALUE;
XContentParser.Token token;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
fieldName = parser.currentName();
@ -66,7 +66,6 @@ public class HistogramFacetCollectorParser implements FacetCollectorParser {
if (interval < 0) {
throw new FacetPhaseExecutionException(facetName, "[interval] is required to be positive for histogram facet");
}
return new HistogramFacetCollector(facetName, field, interval, comparatorType, context.fieldDataCache(), context.mapperService());
}
}

View File

@ -47,11 +47,11 @@ public class QueryFacetCollector extends AbstractFacetCollector {
this.filter = filterCache.cache(new QueryWrapperFilter(query));
}
@Override public void setNextReader(IndexReader reader, int docBase) throws IOException {
@Override protected void doSetNextReader(IndexReader reader, int docBase) throws IOException {
docSet = DocSets.convert(reader, filter.getDocIdSet(reader));
}
@Override public void collect(int doc) throws IOException {
@Override protected void doCollect(int doc) throws IOException {
if (docSet.get(doc)) {
count++;
}

View File

@ -60,11 +60,11 @@ public class StatisticalFacetCollector extends AbstractFacetCollector {
fieldDataType = mapper.fieldDataType();
}
@Override public void collect(int doc) throws IOException {
@Override protected void doCollect(int doc) throws IOException {
fieldData.forEachValueInDoc(doc, statsProc);
}
@Override public void setNextReader(IndexReader reader, int docBase) throws IOException {
@Override protected void doSetNextReader(IndexReader reader, int docBase) throws IOException {
fieldData = (NumericFieldData) fieldDataCache.cache(fieldDataType, reader, fieldName, fieldDataOptions().withFreqs(false));
}

View File

@ -19,8 +19,12 @@
package org.elasticsearch.search.facets.support;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Scorer;
import org.elasticsearch.search.facets.collector.FacetCollector;
import org.elasticsearch.util.lucene.docset.DocSet;
import org.elasticsearch.util.lucene.docset.DocSets;
import java.io.IOException;
@ -31,10 +35,18 @@ public abstract class AbstractFacetCollector extends FacetCollector {
protected final String facetName;
protected Filter filter;
private DocSet docSet = null;
public AbstractFacetCollector(String facetName) {
this.facetName = facetName;
}
@Override public void setFilter(Filter filter) {
this.filter = filter;
}
@Override public void setScorer(Scorer scorer) throws IOException {
// usually, there is nothing to do here
}
@ -42,4 +54,23 @@ public abstract class AbstractFacetCollector extends FacetCollector {
@Override public boolean acceptsDocsOutOfOrder() {
return true; // when working on FieldData, docs can be out of order
}
@Override public void setNextReader(IndexReader reader, int docBase) throws IOException {
if (filter != null) {
docSet = DocSets.convert(reader, filter.getDocIdSet(reader));
}
doSetNextReader(reader, docBase);
}
protected abstract void doSetNextReader(IndexReader reader, int docBase) throws IOException;
@Override public void collect(int doc) throws IOException {
if (docSet == null) {
doCollect(doc);
} else if (docSet.get(doc)) {
doCollect(doc);
}
}
protected abstract void doCollect(int doc) throws IOException;
}

View File

@ -79,11 +79,11 @@ public class TermsFacetCollector extends AbstractFacetCollector {
aggregator = new AggregatorValueProc(popFacets());
}
@Override public void setNextReader(IndexReader reader, int docBase) throws IOException {
@Override protected void doSetNextReader(IndexReader reader, int docBase) throws IOException {
fieldData = fieldDataCache.cache(fieldDataType, reader, fieldName, fieldDataOptions().withFreqs(false));
}
@Override public void collect(int doc) throws IOException {
@Override protected void doCollect(int doc) throws IOException {
fieldData.forEachValueInDoc(doc, aggregator);
}

View File

@ -41,15 +41,15 @@ public class TermsFacetCollectorParser implements FacetCollectorParser {
String field = null;
int size = 10;
String termFieldName = null;
String fieldName = null;
XContentParser.Token token;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
termFieldName = parser.currentName();
fieldName = parser.currentName();
} else if (token.isValue()) {
if ("field".equals(termFieldName)) {
if ("field".equals(fieldName)) {
field = parser.text();
} else if ("size".equals(termFieldName)) {
} else if ("size".equals(fieldName)) {
size = parser.intValue();
}
}

View File

@ -30,13 +30,14 @@ import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.elasticsearch.index.query.xcontent.FilterBuilders.*;
import static org.elasticsearch.index.query.xcontent.QueryBuilders.*;
import static org.elasticsearch.util.xcontent.XContentFactory.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
/**
* @author kimchy (Shay Banon)
* @author kimchy (shay.banon)
*/
public class SimpleFacetsTests extends AbstractNodesTests {
@ -96,6 +97,17 @@ public class SimpleFacetsTests extends AbstractNodesTests {
assertThat(facet.entries().size(), equalTo(3));
assertThat(facet.entries().get(0).term(), equalTo("yyy"));
assertThat(facet.entries().get(0).count(), equalTo(2));
searchResponse = client.prepareSearch()
.setQuery(matchAllQuery())
.addFacetTerms("facet1", "stag", 10, termFilter("tag", "xxx"))
.execute().actionGet();
facet = searchResponse.facets().facet(TermsFacet.class, "facet1");
assertThat(facet.name(), equalTo("facet1"));
assertThat(facet.entries().size(), equalTo(1));
assertThat(facet.entries().get(0).term(), equalTo("111"));
assertThat(facet.entries().get(0).count(), equalTo(1));
}
@Test public void testStatsFacets() throws Exception {