Search Facets: Facets to allow to define filters on them, closes #217.
This commit is contained in:
parent
6257b78243
commit
5ca050ffcb
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue