Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ public Class<?> getWrappedClass() {
return first.getClass();
}

public Aggregator getWrapped() {
return first;
}

@Override
public String name() {
return first.name();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void collect(int doc, long bucket) throws IOException {

@Override
public double metric(long owningBucketOrd) {
return valuesSource == null ? 0 : counts.get(owningBucketOrd);
return valuesSource == null || owningBucketOrd >= counts.size() ? 0 : counts.get(owningBucketOrd);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationExecutionException;
import org.elasticsearch.search.aggregations.Aggregator;
import org.elasticsearch.search.aggregations.AggregatorFactory;
import org.elasticsearch.search.aggregations.HasAggregations;
import org.elasticsearch.search.aggregations.bucket.SingleBucketAggregation;
import org.elasticsearch.search.aggregations.bucket.SingleBucketAggregator;
Expand Down Expand Up @@ -257,6 +258,9 @@ public Aggregator resolveAggregator(Aggregator root) {
for (int i = 0; i < pathElements.size(); i++) {
AggregationPath.PathElement token = pathElements.get(i);
aggregator = aggregator.subAggregator(token.name);
if (aggregator instanceof AggregatorFactory.MultiBucketAggregatorWrapper) {
aggregator = ((AggregatorFactory.MultiBucketAggregatorWrapper) aggregator).getWrapped();
}
assert (aggregator instanceof SingleBucketAggregator && i <= pathElements.size() - 1)
|| (aggregator instanceof NumericMetricsAggregator && i == pathElements.size() - 1) :
"this should be picked up before aggregation execution - on validate";
Expand All @@ -273,6 +277,9 @@ public Aggregator resolveAggregator(Aggregator root) {
public Aggregator resolveTopmostAggregator(Aggregator root) {
AggregationPath.PathElement token = pathElements.get(0);
Aggregator aggregator = root.subAggregator(token.name);
if (aggregator instanceof AggregatorFactory.MultiBucketAggregatorWrapper) {
aggregator = ((AggregatorFactory.MultiBucketAggregatorWrapper) aggregator).getWrapped();
}
assert (aggregator instanceof SingleBucketAggregator )
|| (aggregator instanceof NumericMetricsAggregator) : "this should be picked up before aggregation execution - on validate";
return aggregator;
Expand All @@ -295,6 +302,9 @@ public void validate(Aggregator root) {

// we're in the middle of the path, so the aggregator can only be a single-bucket aggregator

if (aggregator instanceof AggregatorFactory.MultiBucketAggregatorWrapper) {
aggregator = ((AggregatorFactory.MultiBucketAggregatorWrapper) aggregator).getWrapped();
}
if (!(aggregator instanceof SingleBucketAggregator)) {
throw new AggregationExecutionException("Invalid terms aggregation order path [" + this +
"]. Terms buckets can only be sorted on a sub-aggregator path " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,21 @@
import org.elasticsearch.search.aggregations.metrics.max.Max;
import org.elasticsearch.search.aggregations.metrics.stats.Stats;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount;
import org.elasticsearch.test.ESIntegTestCase;
import org.hamcrest.Matchers;

import java.util.ArrayList;
import java.util.List;

import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.nestedQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.count;
import static org.elasticsearch.search.aggregations.AggregationBuilders.filter;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.max;
Expand Down Expand Up @@ -667,4 +670,111 @@ public void testFilterAggInsideNestedAgg() throws Exception {
numStringParams = bucket.getAggregations().get("num_string_params");
assertThat(numStringParams.getDocCount(), equalTo(0L));
}

public void testTermsOrderByNested() throws Exception {
// Mostly copied over from org.elasticsearch.search.aggregations.bucket.ReverseNestedIT#testSameParentDocHavingMultipleBuckets
XContentBuilder mapping = jsonBuilder().startObject().startObject("product").field("dynamic", "strict").startObject("properties")
.startObject("id").field("type", "long").endObject()
.startObject("sku")
.field("type", "nested")
.startObject("properties")
.startObject("sku_type").field("type", "keyword").endObject()
.startObject("colors")
.field("type", "nested")
.startObject("properties")
.startObject("name").field("type", "keyword").endObject()
.endObject()
.endObject()
.endObject()
.endObject()
.endObject().endObject().endObject();
assertAcked(
prepareCreate("idx3")
.setSettings(Settings.builder().put(SETTING_NUMBER_OF_SHARDS, 1).put(SETTING_NUMBER_OF_REPLICAS, 0))
.addMapping("product", mapping)
);

client().prepareIndex("idx3", "product", "1").setRefreshPolicy(IMMEDIATE).setSource(
jsonBuilder()
.startObject()
.startArray("sku")
.startObject()
.field("sku_type", "bar1")
.startArray("colors")
.startObject().field("name", "red").endObject()
.startObject().field("name", "green").endObject()
.startObject().field("name", "yellow").endObject()
.endArray()
.endObject()
.startObject()
.field("sku_type", "bar1")
.startArray("colors")
.startObject().field("name", "red").endObject()
.startObject().field("name", "blue").endObject()
.startObject().field("name", "white").endObject()
.endArray()
.endObject()
.startObject()
.field("sku_type", "bar1")
.startArray("colors")
.startObject().field("name", "black").endObject()
.startObject().field("name", "blue").endObject()
.endArray()
.endObject()
.startObject()
.field("sku_type", "bar2")
.startArray("colors")
.startObject().field("name", "orange").endObject()
.endArray()
.endObject()
.startObject()
.field("sku_type", "bar2")
.startArray("colors")
.startObject().field("name", "pink").endObject()
.endArray()
.endObject()
.endArray()
.endObject()
).get();

SearchResponse response = client().prepareSearch("idx3")
.addAggregation(
nested("nested_0", "sku").subAggregation(
terms("by_sku").field("sku.sku_type")
.order(Terms.Order.aggregation("nested_1>colors_count", false))
.subAggregation(
nested("nested_1", "sku.colors").subAggregation(
count("colors_count").field("sku.colors.name")
)
)
)
).get();
assertNoFailures(response);
assertHitCount(response, 1);

Nested nested0 = response.getAggregations().get("nested_0");
assertThat(nested0.getDocCount(), equalTo(5L));
Terms terms = nested0.getAggregations().get("by_sku");
assertThat(terms.getBuckets().size(), equalTo(2));

Terms.Bucket bar1 = terms.getBuckets().get(0);
{
Nested nested1 = bar1.getAggregations().get("nested_1");
ValueCount colors_count = nested1.getAggregations().get("colors_count");
assertThat(bar1.getKey(), equalTo("bar1"));
assertThat(bar1.getDocCount(), equalTo(3L));
assertThat(nested1.getDocCount(), equalTo(8L));
assertThat(colors_count.getValue(), equalTo(8L));
}

Terms.Bucket bar2 = terms.getBuckets().get(1);
{
Nested nested1 = bar2.getAggregations().get("nested_1");
ValueCount colors_count = nested1.getAggregations().get("colors_count");
assertThat(bar2.getKey(), equalTo("bar2"));
assertThat(bar2.getDocCount(), equalTo(2L));
assertThat(nested1.getDocCount(), equalTo(2L));
assertThat(colors_count.getValue(), equalTo(2L));
}
}
}