Aggregations: Added getProperty method to Aggregations

This allows arbitrary properties to be retrieved from an aggregation tree. The property is specified using the same syntax as the
order parameter in the terms aggregation. If a property path contians a multi-bucket aggregation the property values from each bucket will be returned in an array.
This commit is contained in:
Colin Goodheart-Smithe 2014-10-28 10:39:29 +00:00
parent 856b294441
commit c420a17f7d
54 changed files with 1077 additions and 162 deletions

View File

@ -30,6 +30,15 @@ public interface Aggregation {
*/
String getName();
/**
* Get the value of specified path in the aggregation.
*
* @param path
* the path to the property in the aggregation tree
* @return the value of the property
*/
Object getProperty(String path);
/**
* Get the optional byte array metadata that was set on the aggregation
*/

View File

@ -46,4 +46,13 @@ public interface Aggregations extends Iterable<Aggregation> {
*/
<A extends Aggregation> A get(String name);
/**
* Get the value of specified path in the aggregation.
*
* @param path
* the path to the property in the aggregation tree
* @return the value of the property
*/
Object getProperty(String path);
}

View File

@ -29,6 +29,7 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentBuilderString;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.aggregations.support.AggregationPath;
import java.io.IOException;
import java.util.List;
@ -147,6 +148,13 @@ public abstract class InternalAggregation implements Aggregation, ToXContent, St
*/
public abstract InternalAggregation reduce(ReduceContext reduceContext);
public Object getProperty(String path) {
AggregationPath aggPath = AggregationPath.parse(path);
return getProperty(aggPath.getPathElementsAsStringList());
}
public abstract Object getProperty(List<String> path);
/**
* Read a size under the assumption that a value of 0 means unlimited.
*/

View File

@ -19,7 +19,13 @@
package org.elasticsearch.search.aggregations;
import com.google.common.base.Function;
import com.google.common.collect.*;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
@ -28,9 +34,14 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentBuilderString;
import org.elasticsearch.search.aggregations.InternalAggregation.ReduceContext;
import org.elasticsearch.search.aggregations.support.AggregationPath;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static com.google.common.collect.Maps.newHashMap;
@ -106,6 +117,23 @@ public class InternalAggregations implements Aggregations, ToXContent, Streamabl
return (A) asMap().get(name);
}
public Object getProperty(String path) {
AggregationPath aggPath = AggregationPath.parse(path);
return getProperty(aggPath.getPathElementsAsStringList());
}
public Object getProperty(List<String> path) {
if (path.isEmpty()) {
return this;
}
String aggName = path.get(0);
InternalAggregation aggregation = get(aggName);
if (aggregation == null) {
throw new ElasticsearchIllegalArgumentException("Cannot find an aggregation named [" + aggName + "]");
}
return aggregation.getProperty(path.subList(1, path.size()));
}
/**
* Reduces the given lists of addAggregation.
*

View File

@ -0,0 +1,76 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.search.aggregations;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
import java.util.List;
import java.util.Map;
public abstract class InternalMultiBucketAggregation extends InternalAggregation implements MultiBucketsAggregation {
public InternalMultiBucketAggregation() {
}
public InternalMultiBucketAggregation(String name, Map<String, Object> metaData) {
super(name, metaData);
}
@Override
public Object getProperty(List<String> path) {
if (path.isEmpty()) {
return this;
} else {
List<? extends Bucket> buckets = getBuckets();
Object[] propertyArray = new Object[buckets.size()];
for (int i = 0; i < buckets.size(); i++) {
propertyArray[i] = buckets.get(i).getProperty(getName(), path);
}
return propertyArray;
}
}
public static abstract class InternalBucket implements Bucket {
public Object getProperty(String containingAggName, List<String> path) {
if (path.isEmpty()) {
return this;
}
Aggregations aggregations = getAggregations();
String aggName = path.get(0);
if (aggName.equals("_count")) {
if (path.size() > 1) {
throw new ElasticsearchIllegalArgumentException("_count must be the last element in the path");
}
return getDocCount();
} else if (aggName.equals("_key")) {
if (path.size() > 1) {
throw new ElasticsearchIllegalArgumentException("_key must be the last element in the path");
}
return getKey();
}
InternalAggregation aggregation = aggregations.get(aggName);
if (aggregation == null) {
throw new ElasticsearchIllegalArgumentException("Cannot find an aggregation named [" + aggName + "] in [" + containingAggName + "]");
}
return aggregation.getProperty(path.subList(1, path.size()));
}
}
}

View File

@ -18,7 +18,7 @@
*/
package org.elasticsearch.search.aggregations.bucket;
import org.elasticsearch.common.collect.HppcMaps;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -82,6 +82,26 @@ public abstract class InternalSingleBucketAggregation extends InternalAggregatio
return newAggregation(getName(), docCount, aggs);
}
@Override
public Object getProperty(List<String> path) {
if (path.isEmpty()) {
return this;
} else {
String aggName = path.get(0);
if (aggName.equals("_count")) {
if (path.size() > 1) {
throw new ElasticsearchIllegalArgumentException("_count must be the last element in the path");
}
return getDocCount();
}
InternalAggregation aggregation = aggregations.get(aggName);
if (aggregation == null) {
throw new ElasticsearchIllegalArgumentException("Cannot find an aggregation named [" + aggName + "] in [" + getName() + "]");
}
return aggregation.getProperty(path.subList(1, path.size()));
}
}
@Override
protected void doReadFrom(StreamInput in) throws IOException {
docCount = in.readVLong();

View File

@ -26,7 +26,7 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.HasAggregations;
import org.elasticsearch.search.aggregations.support.OrderPath;
import org.elasticsearch.search.aggregations.support.AggregationPath;
import java.util.Collection;
import java.util.List;
@ -63,21 +63,23 @@ public interface MultiBucketsAggregation extends Aggregation {
*/
Aggregations getAggregations();
Object getProperty(String containingAggName, List<String> path);
static class SubAggregationComparator<B extends Bucket> implements java.util.Comparator<B> {
private final OrderPath path;
private final AggregationPath path;
private final boolean asc;
public SubAggregationComparator(String expression, boolean asc) {
this.asc = asc;
this.path = OrderPath.parse(expression);
this.path = AggregationPath.parse(expression);
}
public boolean asc() {
return asc;
}
public OrderPath path() {
public AggregationPath path() {
return path;
}

View File

@ -25,10 +25,7 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.text.StringText;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.search.aggregations.AggregationStreams;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.InternalAggregation;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.*;
import org.elasticsearch.search.aggregations.bucket.BucketStreamContext;
import org.elasticsearch.search.aggregations.bucket.BucketStreams;
@ -41,7 +38,7 @@ import java.util.Map;
/**
*
*/
public class InternalFilters extends InternalAggregation implements Filters {
public class InternalFilters extends InternalMultiBucketAggregation implements Filters {
public final static Type TYPE = new Type("filters");
@ -75,7 +72,7 @@ public class InternalFilters extends InternalAggregation implements Filters {
BucketStreams.registerStream(BUCKET_STREAM, TYPE.stream());
}
public static class Bucket implements Filters.Bucket {
public static class Bucket extends InternalBucket implements Filters.Bucket {
private final boolean keyed;
private String key;

View File

@ -27,10 +27,7 @@ import org.elasticsearch.common.text.StringText;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.util.LongObjectPagedHashMap;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.search.aggregations.AggregationStreams;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.InternalAggregation;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.*;
import org.elasticsearch.search.aggregations.bucket.BucketStreamContext;
import org.elasticsearch.search.aggregations.bucket.BucketStreams;
@ -42,7 +39,7 @@ import java.util.*;
* All geohashes in a grid are of the same precision and held internally as a single long
* for efficiency's sake.
*/
public class InternalGeoHashGrid extends InternalAggregation implements GeoHashGrid {
public class InternalGeoHashGrid extends InternalMultiBucketAggregation implements GeoHashGrid {
public static final Type TYPE = new Type("geohash_grid", "ghcells");
@ -77,7 +74,7 @@ public class InternalGeoHashGrid extends InternalAggregation implements GeoHashG
}
static class Bucket implements GeoHashGrid.Bucket, Comparable<Bucket> {
static class Bucket extends InternalMultiBucketAggregation.InternalBucket implements GeoHashGrid.Bucket, Comparable<Bucket> {
protected long geohashAsLong;
protected long docCount;

View File

@ -30,10 +30,7 @@ import org.elasticsearch.common.text.StringText;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.util.LongObjectPagedHashMap;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.search.aggregations.AggregationStreams;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.InternalAggregation;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.*;
import org.elasticsearch.search.aggregations.bucket.BucketStreamContext;
import org.elasticsearch.search.aggregations.bucket.BucketStreams;
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
@ -48,7 +45,7 @@ import java.util.Map;
/**
* TODO should be renamed to InternalNumericHistogram (see comment on {@link Histogram})?
*/
public class InternalHistogram<B extends InternalHistogram.Bucket> extends InternalAggregation implements Histogram {
public class InternalHistogram<B extends InternalHistogram.Bucket> extends InternalMultiBucketAggregation implements Histogram {
final static Type TYPE = new Type("histogram", "histo");
final static Factory FACTORY = new Factory();
@ -85,7 +82,7 @@ public class InternalHistogram<B extends InternalHistogram.Bucket> extends Inter
BucketStreams.registerStream(BUCKET_STREAM, TYPE.stream());
}
public static class Bucket implements Histogram.Bucket {
public static class Bucket extends InternalMultiBucketAggregation.InternalBucket implements Histogram.Bucket {
long key;
long docCount;

View File

@ -25,10 +25,7 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.text.StringText;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.search.aggregations.AggregationStreams;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.InternalAggregation;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.*;
import org.elasticsearch.search.aggregations.bucket.BucketStreamContext;
import org.elasticsearch.search.aggregations.bucket.BucketStreams;
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
@ -43,7 +40,7 @@ import java.util.Map;
/**
*
*/
public class InternalRange<B extends InternalRange.Bucket> extends InternalAggregation implements Range {
public class InternalRange<B extends InternalRange.Bucket> extends InternalMultiBucketAggregation implements Range {
static final Factory FACTORY = new Factory();
@ -80,7 +77,7 @@ public class InternalRange<B extends InternalRange.Bucket> extends InternalAggre
BucketStreams.registerStream(BUCKET_STREAM, TYPE.stream());
}
public static class Bucket implements Range.Bucket {
public static class Bucket extends InternalMultiBucketAggregation.InternalBucket implements Range.Bucket {
protected transient final boolean keyed;
protected transient final ValueFormatter formatter;

View File

@ -24,6 +24,7 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.InternalAggregation;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.InternalMultiBucketAggregation;
import org.elasticsearch.search.aggregations.bucket.significant.heuristics.SignificanceHeuristic;
import java.util.*;
@ -31,7 +32,7 @@ import java.util.*;
/**
*
*/
public abstract class InternalSignificantTerms extends InternalAggregation implements SignificantTerms, ToXContent, Streamable {
public abstract class InternalSignificantTerms extends InternalMultiBucketAggregation implements SignificantTerms, ToXContent, Streamable {
protected SignificanceHeuristic significanceHeuristic;
protected int requiredSize;

View File

@ -18,6 +18,7 @@
*/
package org.elasticsearch.search.aggregations.bucket.significant;
import org.elasticsearch.search.aggregations.InternalMultiBucketAggregation;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
import java.util.List;
@ -28,7 +29,7 @@ import java.util.List;
public interface SignificantTerms extends MultiBucketsAggregation, Iterable<SignificantTerms.Bucket> {
static abstract class Bucket implements MultiBucketsAggregation.Bucket {
static abstract class Bucket extends InternalMultiBucketAggregation.InternalBucket {
long subsetDf;
long subsetSize;

View File

@ -30,10 +30,15 @@ import org.elasticsearch.search.aggregations.bucket.SingleBucketAggregator;
import org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket;
import org.elasticsearch.search.aggregations.bucket.terms.Terms.Order;
import org.elasticsearch.search.aggregations.metrics.NumericMetricsAggregator;
import org.elasticsearch.search.aggregations.support.OrderPath;
import org.elasticsearch.search.aggregations.support.AggregationPath;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
*
@ -136,7 +141,7 @@ class InternalOrder extends Terms.Order {
} else if (!(order instanceof Aggregation)) {
return order;
}
OrderPath path = ((Aggregation) order).path();
AggregationPath path = ((Aggregation) order).path();
path.validate(termsAggregator);
return order;
}
@ -149,7 +154,7 @@ class InternalOrder extends Terms.Order {
super(ID, key, asc, new MultiBucketsAggregation.Bucket.SubAggregationComparator<Terms.Bucket>(key, asc));
}
OrderPath path() {
AggregationPath path() {
return ((MultiBucketsAggregation.Bucket.SubAggregationComparator) comparator).path();
}
@ -167,9 +172,9 @@ class InternalOrder extends Terms.Order {
// sub aggregation values directly from the sub aggregators bypassing bucket creation. Note that the comparator
// attached to the order will still be used in the reduce phase of the Aggregation.
OrderPath path = path();
AggregationPath path = path();
final Aggregator aggregator = path.resolveAggregator(termsAggregator);
final String key = path.tokens[path.tokens.length - 1].key;
final String key = path.lastPathElement().key;
if (aggregator instanceof SingleBucketAggregator) {
assert key == null : "this should be picked up before the aggregation is executed - on validate";
@ -286,12 +291,12 @@ class InternalOrder extends Terms.Order {
out.writeByte(order.id());
Aggregation aggregationOrder = (Aggregation) order;
out.writeBoolean(((MultiBucketsAggregation.Bucket.SubAggregationComparator) aggregationOrder.comparator).asc());
OrderPath path = ((Aggregation) order).path();
AggregationPath path = ((Aggregation) order).path();
if (out.getVersion().onOrAfter(Version.V_1_1_0)) {
out.writeString(path.toString());
} else {
// prev versions only supported sorting on a single level -> a single token;
OrderPath.Token token = path.lastToken();
AggregationPath.PathElement token = path.lastPathElement();
out.writeString(token.name);
boolean hasValueName = token.key != null;
out.writeBoolean(hasValueName);

View File

@ -28,6 +28,7 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.InternalAggregation;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.InternalMultiBucketAggregation;
import org.elasticsearch.search.aggregations.bucket.terms.support.BucketPriorityQueue;
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
@ -36,7 +37,7 @@ import java.util.*;
/**
*
*/
public abstract class InternalTerms extends InternalAggregation implements Terms, ToXContent, Streamable {
public abstract class InternalTerms extends InternalMultiBucketAggregation implements Terms, ToXContent, Streamable {
protected static final String DOC_COUNT_ERROR_UPPER_BOUND_FIELD_NAME = "doc_count_error_upper_bound";
protected static final String SUM_OF_OTHER_DOC_COUNTS = "sum_other_doc_count";

View File

@ -20,6 +20,7 @@ package org.elasticsearch.search.aggregations.bucket.terms;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.search.aggregations.Aggregator;
import org.elasticsearch.search.aggregations.InternalMultiBucketAggregation;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
import java.util.Arrays;
@ -61,7 +62,7 @@ public interface Terms extends MultiBucketsAggregation {
/**
* A bucket that is associated with a single term
*/
static abstract class Bucket implements MultiBucketsAggregation.Bucket {
static abstract class Bucket extends InternalMultiBucketAggregation.InternalBucket {
public abstract Number getKeyAsNumber();

View File

@ -29,7 +29,7 @@ import org.elasticsearch.search.aggregations.bucket.BucketsAggregator;
import org.elasticsearch.search.aggregations.bucket.terms.InternalOrder.Aggregation;
import org.elasticsearch.search.aggregations.bucket.terms.InternalOrder.CompoundOrder;
import org.elasticsearch.search.aggregations.support.AggregationContext;
import org.elasticsearch.search.aggregations.support.OrderPath;
import org.elasticsearch.search.aggregations.support.AggregationPath;
import java.io.IOException;
import java.util.HashSet;
@ -142,13 +142,13 @@ public abstract class TermsAggregator extends BucketsAggregator {
this.subAggCollectMode = subAggCollectMode;
// Don't defer any child agg if we are dependent on it for pruning results
if (order instanceof Aggregation){
OrderPath path = ((Aggregation) order).path();
AggregationPath path = ((Aggregation) order).path();
aggsUsedForSorting.add(path.resolveTopmostAggregator(this));
} else if (order instanceof CompoundOrder) {
CompoundOrder compoundOrder = (CompoundOrder) order;
for (Terms.Order orderElement : compoundOrder.orderElements()) {
if (orderElement instanceof Aggregation) {
OrderPath path = ((Aggregation) orderElement).path();
AggregationPath path = ((Aggregation) orderElement).path();
aggsUsedForSorting.add(path.resolveTopmostAggregator(this));
}
}

View File

@ -18,8 +18,10 @@
*/
package org.elasticsearch.search.aggregations.metrics;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
import java.util.List;
import java.util.Map;
/**
@ -38,6 +40,18 @@ public abstract class InternalNumericMetricsAggregation extends InternalMetricsA
}
public abstract double value();
@Override
public Object getProperty(List<String> path) {
if (path.isEmpty()) {
return this;
} else if (path.size() == 1 && "value".equals(path.get(0))) {
return value();
} else {
throw new ElasticsearchIllegalArgumentException("path not supported for [" + getName() + "]: " + path);
}
}
}
public static abstract class MultiValue extends InternalNumericMetricsAggregation {
@ -50,6 +64,16 @@ public abstract class InternalNumericMetricsAggregation extends InternalMetricsA
public abstract double value(String name);
@Override
public Object getProperty(List<String> path) {
if (path.isEmpty()) {
return this;
} else if (path.size() == 1) {
return value(path.get(0));
} else {
throw new ElasticsearchIllegalArgumentException("path not supported for [" + getName() + "]: " + path);
}
}
}
private InternalNumericMetricsAggregation() {} // for serialization

View File

@ -19,6 +19,7 @@
package org.elasticsearch.search.aggregations.metrics.geobounds;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
@ -28,6 +29,7 @@ import org.elasticsearch.search.aggregations.InternalAggregation;
import org.elasticsearch.search.aggregations.metrics.InternalMetricsAggregation;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class InternalGeoBounds extends InternalMetricsAggregation implements GeoBounds {
@ -103,7 +105,54 @@ public class InternalGeoBounds extends InternalMetricsAggregation implements Geo
}
return new InternalGeoBounds(name, top, bottom, posLeft, posRight, negLeft, negRight, wrapLongitude, getMetaData());
}
@Override
public Object getProperty(List<String> path) {
if (path.isEmpty()) {
return this;
} else if (path.size() == 1) {
BoundingBox boundingBox = resolveBoundingBox();
String bBoxSide = path.get(0);
switch (bBoxSide) {
case "top":
return boundingBox.topLeft.lat();
case "left":
return boundingBox.topLeft.lon();
case "bottom":
return boundingBox.bottomRight.lat();
case "right":
return boundingBox.bottomRight.lon();
default:
throw new ElasticsearchIllegalArgumentException("Found unknown path element [" + bBoxSide + "] in [" + getName() + "]");
}
} else if (path.size() == 2) {
BoundingBox boundingBox = resolveBoundingBox();
GeoPoint cornerPoint = null;
String cornerString = path.get(0);
switch (cornerString) {
case "top_left":
cornerPoint = boundingBox.topLeft;
break;
case "bottom_right":
cornerPoint = boundingBox.bottomRight;
break;
default:
throw new ElasticsearchIllegalArgumentException("Found unknown path element [" + cornerString + "] in [" + getName() + "]");
}
String latLonString = path.get(1);
switch (latLonString) {
case "lat":
return cornerPoint.lat();
case "lon":
return cornerPoint.lon();
default:
throw new ElasticsearchIllegalArgumentException("Found unknown path element [" + latLonString + "] in [" + getName() + "]");
}
} else {
throw new ElasticsearchIllegalArgumentException("path not supported for [" + getName() + "]: " + path);
}
}
@Override
public XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException {
GeoPoint topLeft = topLeft();

View File

@ -19,6 +19,7 @@
package org.elasticsearch.search.aggregations.metrics.scripted;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -112,6 +113,16 @@ public class InternalScriptedMetric extends InternalMetricsAggregation implement
return TYPE;
}
public Object getProperty(List<String> path) {
if (path.isEmpty()) {
return this;
} else if (path.size() == 1 && "value".equals(path.get(0))) {
return aggregation;
} else {
throw new ElasticsearchIllegalArgumentException("path not supported for [" + getName() + "]: " + path);
}
}
@Override
protected void doReadFrom(StreamInput in) throws IOException {
scriptLang = in.readOptionalString();

View File

@ -18,10 +18,14 @@
*/
package org.elasticsearch.search.aggregations.metrics.tophits;
import java.io.IOException;
import java.util.List;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.TopFieldDocs;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
@ -34,10 +38,6 @@ import org.elasticsearch.search.aggregations.metrics.InternalMetricsAggregation;
import org.elasticsearch.search.internal.InternalSearchHit;
import org.elasticsearch.search.internal.InternalSearchHits;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
*/
public class InternalTopHits extends InternalMetricsAggregation implements TopHits {
@ -129,6 +129,15 @@ public class InternalTopHits extends InternalMetricsAggregation implements TopHi
}
}
@Override
public Object getProperty(List<String> path) {
if (path.isEmpty()) {
return this;
} else {
throw new ElasticsearchIllegalArgumentException("path not supported for [" + getName() + "]: " + path);
}
}
@Override
protected void doReadFrom(StreamInput in) throws IOException {
from = in.readVInt();

View File

@ -30,6 +30,9 @@ import org.elasticsearch.search.aggregations.bucket.SingleBucketAggregator;
import org.elasticsearch.search.aggregations.metrics.InternalNumericMetricsAggregation;
import org.elasticsearch.search.aggregations.metrics.NumericMetricsAggregator;
import java.util.ArrayList;
import java.util.List;
/**
* A path that can be used to sort/order buckets (in some multi-bucket aggregations, eg terms & histogram) based on
* sub-aggregations. The path may point to either a single-bucket aggregation or a metrics aggregation. If the path
@ -61,13 +64,13 @@ import org.elasticsearch.search.aggregations.metrics.NumericMetricsAggregator;
* </ul>
*
*/
public class OrderPath {
public class AggregationPath {
private final static String AGG_DELIM = ">";
public static OrderPath parse(String path) {
public static AggregationPath parse(String path) {
String[] elements = Strings.tokenizeToStringArray(path, AGG_DELIM);
Token[] tokens = new Token[elements.length];
List<PathElement> tokens = new ArrayList<>(elements.length);
String[] tuple = new String[2];
for (int i = 0; i < elements.length; i++) {
String element = elements[i];
@ -80,19 +83,19 @@ public class OrderPath {
if (element.charAt(element.length() - 1) != ']') {
throw new AggregationExecutionException("Invalid path element [" + element + "] in path [" + path + "]");
}
tokens[i] = new Token(element, element.substring(0, index), element.substring(index + 1, element.length() - 1));
tokens.add(new PathElement(element, element.substring(0, index), element.substring(index + 1, element.length() - 1)));
continue;
}
index = element.lastIndexOf('.');
if (index < 0) {
tokens[i] = new Token(element, element, null);
tokens.add(new PathElement(element, element, null));
continue;
}
if (index == 0 || index > element.length() - 2) {
throw new AggregationExecutionException("Invalid path element [" + element + "] in path [" + path + "]");
}
tuple = split(element, index, tuple);
tokens[i] = new Token(element, tuple[0], tuple[1]);
tokens.add(new PathElement(element, tuple[0], tuple[1]));
} else {
int index = element.lastIndexOf('[');
@ -103,22 +106,22 @@ public class OrderPath {
if (element.charAt(element.length() - 1) != ']') {
throw new AggregationExecutionException("Invalid path element [" + element + "] in path [" + path + "]");
}
tokens[i] = new Token(element, element.substring(0, index), element.substring(index + 1, element.length() - 1));
tokens.add(new PathElement(element, element.substring(0, index), element.substring(index + 1, element.length() - 1)));
continue;
}
tokens[i] = new Token(element, element, null);
tokens.add(new PathElement(element, element, null));
}
}
return new OrderPath(tokens);
return new AggregationPath(tokens);
}
public static class Token {
public static class PathElement {
private final String fullName;
public final String name;
public final String key;
public Token(String fullName, String name, String key) {
public PathElement(String fullName, String name, String key) {
this.fullName = fullName;
this.name = name;
this.key = key;
@ -129,7 +132,7 @@ public class OrderPath {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Token token = (Token) o;
PathElement token = (PathElement) o;
if (key != null ? !key.equals(token.key) : token.key != null) return false;
if (!name.equals(token.name)) return false;
@ -150,28 +153,43 @@ public class OrderPath {
}
}
public final Token[] tokens;
private final List<PathElement> pathElements;
public OrderPath(Token[] tokens) {
this.tokens = tokens;
if (tokens == null || tokens.length == 0) {
public AggregationPath(List<PathElement> tokens) {
this.pathElements = tokens;
if (tokens == null || tokens.size() == 0) {
throw new ElasticsearchIllegalArgumentException("Invalid path [" + this + "]");
}
}
@Override
public String toString() {
return Strings.arrayToDelimitedString(tokens, AGG_DELIM);
return Strings.arrayToDelimitedString(pathElements.toArray(), AGG_DELIM);
}
public Token lastToken() {
return tokens[tokens.length - 1];
public PathElement lastPathElement() {
return pathElements.get(pathElements.size() - 1);
}
public OrderPath subPath(int offset, int length) {
Token[] subTokens = new Token[length];
System.arraycopy(tokens, offset, subTokens, 0, length);
return new OrderPath(tokens);
public List<PathElement> getPathElements() {
return this.pathElements;
}
public List<String> getPathElementsAsStringList() {
List<String> stringPathElements = new ArrayList<>();
for (PathElement pathElement : this.pathElements) {
stringPathElements.add(pathElement.name);
if (pathElement.key != null) {
stringPathElements.add(pathElement.key);
}
}
return stringPathElements;
}
public AggregationPath subPath(int offset, int length) {
PathElement[] subTokens = new PathElement[length];
System.arraycopy(pathElements, offset, subTokens, 0, length);
return new AggregationPath(pathElements);
}
/**
@ -183,8 +201,8 @@ public class OrderPath {
public double resolveValue(HasAggregations root) {
HasAggregations parent = root;
double value = Double.NaN;
for (int i = 0; i < tokens.length; i++) {
OrderPath.Token token = tokens[i];
for (int i = 0; i < pathElements.size(); i++) {
AggregationPath.PathElement token = pathElements.get(i);
Aggregation agg = parent.getAggregations().get(token.name);
if (agg == null) {
@ -204,9 +222,9 @@ public class OrderPath {
}
// the agg can only be a metrics agg, and a metrics agg must be at the end of the path
if (i != tokens.length - 1) {
if (i != pathElements.size() - 1) {
throw new ElasticsearchIllegalArgumentException("Invalid order path [" + this +
"]. Metrics aggregations cannot have sub-aggregations (at [" + token + ">" + tokens[i+1] + "]");
"]. Metrics aggregations cannot have sub-aggregations (at [" + token + ">" + pathElements.get(i + 1) + "]");
}
if (agg instanceof InternalNumericMetricsAggregation.SingleValue) {
@ -240,11 +258,11 @@ public class OrderPath {
*/
public Aggregator resolveAggregator(Aggregator root) {
Aggregator aggregator = root;
for (int i = 0; i < tokens.length; i++) {
OrderPath.Token token = tokens[i];
for (int i = 0; i < pathElements.size(); i++) {
AggregationPath.PathElement token = pathElements.get(i);
aggregator = aggregator.subAggregator(token.name);
assert (aggregator instanceof SingleBucketAggregator && i <= tokens.length - 1) ||
(aggregator instanceof NumericMetricsAggregator && i == tokens.length - 1) :
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";
}
return aggregator;
@ -257,7 +275,7 @@ public class OrderPath {
* @return The first child aggregator of the root pointed by this path
*/
public Aggregator resolveTopmostAggregator(Aggregator root) {
OrderPath.Token token = tokens[0];
AggregationPath.PathElement token = pathElements.get(0);
Aggregator aggregator = root.subAggregator(token.name);
assert (aggregator instanceof SingleBucketAggregator )
|| (aggregator instanceof NumericMetricsAggregator) : "this should be picked up before aggregation execution - on validate";
@ -271,12 +289,13 @@ public class OrderPath {
*/
public void validate(Aggregator root) {
Aggregator aggregator = root;
for (int i = 0; i < tokens.length; i++) {
aggregator = aggregator.subAggregator(tokens[i].name);
for (int i = 0; i < pathElements.size(); i++) {
aggregator = aggregator.subAggregator(pathElements.get(i).name);
if (aggregator == null) {
throw new AggregationExecutionException("Invalid term-aggregator order path [" + this + "]. Unknown aggregation [" + tokens[i].name + "]");
throw new AggregationExecutionException("Invalid term-aggregator order path [" + this + "]. Unknown aggregation ["
+ pathElements.get(i).name + "]");
}
if (i < tokens.length - 1) {
if (i < pathElements.size() - 1) {
// we're in the middle of the path, so the aggregator can only be a single-bucket aggregator
@ -288,7 +307,7 @@ public class OrderPath {
subPath(0, i + 1) + "] points to non single-bucket aggregation");
}
if (tokens[i].key != null) {
if (pathElements.get(i).key != null) {
throw new AggregationExecutionException("Invalid terms aggregation order path [" + this +
"]. Terms buckets can only be sorted on a sub-aggregator path " +
"that is built out of zero or more single-bucket aggregations within the path and a " +
@ -305,7 +324,7 @@ public class OrderPath {
"single-bucket or a metrics aggregation at the path end.");
}
OrderPath.Token lastToken = lastToken();
AggregationPath.PathElement lastToken = lastPathElement();
if (singleBucket) {
if (lastToken.key != null && !"doc_count".equals(lastToken.key)) {

View File

@ -18,6 +18,13 @@
*/
package org.elasticsearch.search.aggregations.bucket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateResponse;
@ -30,16 +37,18 @@ import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
import java.util.*;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.children;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.search.aggregations.AggregationBuilders.topHits;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
/**
*/
@ -138,8 +147,10 @@ public class ChildrenTests extends ElasticsearchIntegrationTest {
Children childrenBucket = categoryBucket.getAggregations().get("to_comment");
assertThat(childrenBucket.getName(), equalTo("to_comment"));
assertThat(childrenBucket.getDocCount(), equalTo((long) entry1.getValue().commentIds.size()));
assertThat((long) childrenBucket.getProperty("_count"), equalTo((long) entry1.getValue().commentIds.size()));
Terms commentersTerms = childrenBucket.getAggregations().get("commenters");
assertThat((Terms) childrenBucket.getProperty("commenters"), sameInstance(commentersTerms));
assertThat(commentersTerms.getBuckets().size(), equalTo(entry1.getValue().commenterToCommentId.size()));
for (Map.Entry<String, Set<String>> entry2 : entry1.getValue().commenterToCommentId.entrySet()) {
Terms.Bucket commentBucket = commentersTerms.getBucketByKey(entry2.getKey());

View File

@ -46,7 +46,11 @@ import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.dateHistogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.max;
import static org.elasticsearch.search.aggregations.AggregationBuilders.stats;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@ -349,6 +353,9 @@ public class DateHistogramTests extends ElasticsearchIntegrationTest {
assertThat(histo, notNullValue());
assertThat(histo.getName(), equalTo("histo"));
assertThat(histo.getBuckets().size(), equalTo(3));
Object[] propertiesKeys = (Object[]) histo.getProperty("_key");
Object[] propertiesDocCounts = (Object[]) histo.getProperty("_count");
Object[] propertiesCounts = (Object[]) histo.getProperty("sum.value");
long key = new DateTime(2012, 1, 1, 0, 0, DateTimeZone.UTC).getMillis();
DateHistogram.Bucket bucket = histo.getBucketByKey(key);
@ -358,6 +365,9 @@ public class DateHistogramTests extends ElasticsearchIntegrationTest {
Sum sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getValue(), equalTo(1.0));
assertThat((String) propertiesKeys[0], equalTo("2012-01-01T00:00:00.000Z"));
assertThat((long) propertiesDocCounts[0], equalTo(1l));
assertThat((double) propertiesCounts[0], equalTo(1.0));
key = new DateTime(2012, 2, 1, 0, 0, DateTimeZone.UTC).getMillis();
bucket = histo.getBucketByKey(key);
@ -367,6 +377,9 @@ public class DateHistogramTests extends ElasticsearchIntegrationTest {
sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getValue(), equalTo(5.0));
assertThat((String) propertiesKeys[1], equalTo("2012-02-01T00:00:00.000Z"));
assertThat((long) propertiesDocCounts[1], equalTo(2l));
assertThat((double) propertiesCounts[1], equalTo(5.0));
key = new DateTime(2012, 3, 1, 0, 0, DateTimeZone.UTC).getMillis();
bucket = histo.getBucketByKey(key);
@ -376,6 +389,9 @@ public class DateHistogramTests extends ElasticsearchIntegrationTest {
sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getValue(), equalTo(15.0));
assertThat((String) propertiesKeys[2], equalTo("2012-03-01T00:00:00.000Z"));
assertThat((long) propertiesDocCounts[2], equalTo(3l));
assertThat((double) propertiesCounts[2], equalTo(15.0));
}
@Test

View File

@ -38,7 +38,11 @@ import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.dateRange;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.max;
import static org.elasticsearch.search.aggregations.AggregationBuilders.min;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
@ -392,6 +396,9 @@ public class DateRangeTests extends ElasticsearchIntegrationTest {
assertThat(range, notNullValue());
assertThat(range.getName(), equalTo("range"));
assertThat(range.getBuckets().size(), equalTo(3));
Object[] propertiesKeys = (Object[]) range.getProperty("_key");
Object[] propertiesDocCounts = (Object[]) range.getProperty("_count");
Object[] propertiesCounts = (Object[]) range.getProperty("sum.value");
DateRange.Bucket bucket = range.getBucketByKey("r1");
assertThat(bucket, notNullValue());
@ -404,6 +411,9 @@ public class DateRangeTests extends ElasticsearchIntegrationTest {
Sum sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getValue(), equalTo((double) 1 + 2));
assertThat((String) propertiesKeys[0], equalTo("r1"));
assertThat((long) propertiesDocCounts[0], equalTo(2l));
assertThat((double) propertiesCounts[0], equalTo((double) 1 + 2));
bucket = range.getBucketByKey("r2");
assertThat(bucket, notNullValue());
@ -416,6 +426,9 @@ public class DateRangeTests extends ElasticsearchIntegrationTest {
sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getValue(), equalTo((double) 3 + 4));
assertThat((String) propertiesKeys[1], equalTo("r2"));
assertThat((long) propertiesDocCounts[1], equalTo(2l));
assertThat((double) propertiesCounts[1], equalTo((double) 3 + 4));
bucket = range.getBucketByKey("r3");
assertThat(bucket, notNullValue());
@ -427,6 +440,8 @@ public class DateRangeTests extends ElasticsearchIntegrationTest {
assertThat(bucket.getDocCount(), equalTo(numDocs - 4l));
sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat((String) propertiesKeys[2], equalTo("r3"));
assertThat((long) propertiesDocCounts[2], equalTo(numDocs - 4l));
}
@Test

View File

@ -37,12 +37,23 @@ import org.hamcrest.Matchers;
import org.junit.Test;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.functionScoreQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.avg;
import static org.elasticsearch.search.aggregations.AggregationBuilders.extendedStats;
import static org.elasticsearch.search.aggregations.AggregationBuilders.filter;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.max;
import static org.elasticsearch.search.aggregations.AggregationBuilders.stats;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
@ -382,6 +393,9 @@ public class DoubleTermsTests extends AbstractTermsTests {
assertThat(terms, notNullValue());
assertThat(terms.getName(), equalTo("terms"));
assertThat(terms.getBuckets().size(), equalTo(5));
Object[] propertiesKeys = (Object[]) terms.getProperty("_key");
Object[] propertiesDocCounts = (Object[]) terms.getProperty("_count");
Object[] propertiesCounts = (Object[]) terms.getProperty("sum.value");
for (int i = 0; i < 5; i++) {
Terms.Bucket bucket = terms.getBucketByKey("" + (double) i);
@ -392,6 +406,9 @@ public class DoubleTermsTests extends AbstractTermsTests {
Sum sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat((long) sum.getValue(), equalTo(i+i+1l));
assertThat((String) propertiesKeys[i], equalTo(String.valueOf((double) i)));
assertThat((long) propertiesDocCounts[i], equalTo(1l));
assertThat((double) propertiesCounts[i], equalTo((double) i + i + 1l));
}
}

View File

@ -136,6 +136,7 @@ public class FilterTests extends ElasticsearchIntegrationTest {
assertThat(filter, notNullValue());
assertThat(filter.getName(), equalTo("tag1"));
assertThat(filter.getDocCount(), equalTo((long) numTag1Docs));
assertThat((long) filter.getProperty("_count"), equalTo((long) numTag1Docs));
long sum = 0;
for (int i = 0; i < numTag1Docs; ++i) {
@ -146,6 +147,7 @@ public class FilterTests extends ElasticsearchIntegrationTest {
assertThat(avgValue, notNullValue());
assertThat(avgValue.getName(), equalTo("avg_value"));
assertThat(avgValue.getValue(), equalTo((double) sum / numTag1Docs));
assertThat((double) filter.getProperty("avg_value.value"), equalTo((double) sum / numTag1Docs));
}
@Test

View File

@ -164,6 +164,9 @@ public class FiltersTests extends ElasticsearchIntegrationTest {
assertThat(filters.getName(), equalTo("tags"));
assertThat(filters.getBuckets().size(), equalTo(2));
Object[] propertiesKeys = (Object[]) filters.getProperty("_key");
Object[] propertiesDocCounts = (Object[]) filters.getProperty("_count");
Object[] propertiesCounts = (Object[]) filters.getProperty("avg_value.value");
Filters.Bucket bucket = filters.getBucketByKey("tag1");
assertThat(bucket, Matchers.notNullValue());
@ -177,6 +180,9 @@ public class FiltersTests extends ElasticsearchIntegrationTest {
assertThat(avgValue, notNullValue());
assertThat(avgValue.getName(), equalTo("avg_value"));
assertThat(avgValue.getValue(), equalTo((double) sum / numTag1Docs));
assertThat((String) propertiesKeys[0], equalTo("tag1"));
assertThat((long) propertiesDocCounts[0], equalTo((long) numTag1Docs));
assertThat((double) propertiesCounts[0], equalTo((double) sum / numTag1Docs));
bucket = filters.getBucketByKey("tag2");
assertThat(bucket, Matchers.notNullValue());
@ -190,6 +196,9 @@ public class FiltersTests extends ElasticsearchIntegrationTest {
assertThat(avgValue, notNullValue());
assertThat(avgValue.getName(), equalTo("avg_value"));
assertThat(avgValue.getValue(), equalTo((double) sum / numTag2Docs));
assertThat((String) propertiesKeys[1], equalTo("tag2"));
assertThat((long) propertiesDocCounts[1], equalTo((long) numTag2Docs));
assertThat((double) propertiesCounts[1], equalTo((double) sum / numTag2Docs));
}
@Test

View File

@ -18,7 +18,13 @@
*/
package org.elasticsearch.search.aggregations.bucket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import com.google.common.collect.Sets;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.unit.DistanceUnit;
@ -31,17 +37,15 @@ import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.hamcrest.Matchers;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.geoDistance;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
import static org.hamcrest.core.IsNull.notNullValue;
/**
@ -309,6 +313,9 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertThat(geoDist, notNullValue());
assertThat(geoDist.getName(), equalTo("amsterdam_rings"));
assertThat(geoDist.getBuckets().size(), equalTo(3));
Object[] propertiesKeys = (Object[]) geoDist.getProperty("_key");
Object[] propertiesDocCounts = (Object[]) geoDist.getProperty("_count");
Object[] propertiesCities = (Object[]) geoDist.getProperty("cities");
GeoDistance.Bucket bucket = geoDist.getBucketByKey("*-500.0");
assertThat(bucket, notNullValue());
@ -324,6 +331,9 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
names.add(city.getKey());
}
assertThat(names.contains("utrecht") && names.contains("haarlem"), is(true));
assertThat((String) propertiesKeys[0], equalTo("*-500.0"));
assertThat((long) propertiesDocCounts[0], equalTo(2l));
assertThat((Terms) propertiesCities[0], sameInstance(cities));
bucket = geoDist.getBucketByKey("500.0-1000.0");
assertThat(bucket, notNullValue());
@ -339,6 +349,9 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
names.add(city.getKey());
}
assertThat(names.contains("berlin") && names.contains("prague"), is(true));
assertThat((String) propertiesKeys[1], equalTo("500.0-1000.0"));
assertThat((long) propertiesDocCounts[1], equalTo(2l));
assertThat((Terms) propertiesCities[1], sameInstance(cities));
bucket = geoDist.getBucketByKey("1000.0-*");
assertThat(bucket, notNullValue());
@ -354,6 +367,9 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
names.add(city.getKey());
}
assertThat(names.contains("tel-aviv"), is(true));
assertThat((String) propertiesKeys[2], equalTo("1000.0-*"));
assertThat((long) propertiesDocCounts[2], equalTo(1l));
assertThat((Terms) propertiesCities[2], sameInstance(cities));
}
@Test

View File

@ -21,6 +21,7 @@ package org.elasticsearch.search.aggregations.bucket;
import com.carrotsearch.hppc.ObjectIntMap;
import com.carrotsearch.hppc.ObjectIntOpenHashMap;
import com.carrotsearch.hppc.cursors.ObjectIntCursor;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.geo.GeoHashUtils;
@ -29,6 +30,7 @@ import org.elasticsearch.index.query.GeoBoundingBoxFilterBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
import org.elasticsearch.search.aggregations.bucket.geogrid.GeoHashGrid;
import org.elasticsearch.search.aggregations.bucket.geogrid.GeoHashGrid.Bucket;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
@ -141,7 +143,11 @@ public class GeoHashGridTests extends ElasticsearchIntegrationTest {
assertSearchResponse(response);
GeoHashGrid geoGrid = response.getAggregations().get("geohashgrid");
for (GeoHashGrid.Bucket cell : geoGrid.getBuckets()) {
List<Bucket> buckets = geoGrid.getBuckets();
Object[] propertiesKeys = (Object[]) geoGrid.getProperty("_key");
Object[] propertiesDocCounts = (Object[]) geoGrid.getProperty("_count");
for (int i = 0; i < buckets.size(); i++) {
GeoHashGrid.Bucket cell = buckets.get(i);
String geohash = cell.getKey();
long bucketCount = cell.getDocCount();
@ -149,6 +155,8 @@ public class GeoHashGridTests extends ElasticsearchIntegrationTest {
assertNotSame(bucketCount, 0);
assertEquals("Geohash " + geohash + " has wrong doc count ",
expectedBucketCount, bucketCount);
assertThat((String) propertiesKeys[i], equalTo(geohash));
assertThat((long) propertiesDocCounts[i], equalTo(bucketCount));
}
}
}

View File

@ -18,6 +18,9 @@
*/
package org.elasticsearch.search.aggregations.bucket;
import java.util.ArrayList;
import java.util.List;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
@ -27,15 +30,13 @@ import org.elasticsearch.search.aggregations.metrics.stats.Stats;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.stats;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
import static org.hamcrest.core.IsNull.notNullValue;
/**
@ -86,9 +87,11 @@ public class GlobalTests extends ElasticsearchIntegrationTest {
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getDocCount(), equalTo((long) numDocs));
assertThat((long) global.getProperty("_count"), equalTo((long) numDocs));
assertThat(global.getAggregations().asList().isEmpty(), is(false));
Stats stats = global.getAggregations().get("value_stats");
assertThat((Stats) global.getProperty("value_stats"), sameInstance(stats));
assertThat(stats, notNullValue());
assertThat(stats.getName(), equalTo("value_stats"));
long sum = 0;

View File

@ -19,6 +19,7 @@
package org.elasticsearch.search.aggregations.bucket;
import com.carrotsearch.hppc.LongOpenHashSet;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.aggregations.Aggregator.SubAggCollectionMode;
@ -39,10 +40,18 @@ import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.FilterBuilders.matchAllFilter;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.filter;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.max;
import static org.elasticsearch.search.aggregations.AggregationBuilders.stats;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.core.IsNull.notNullValue;
/**
@ -293,6 +302,9 @@ public class HistogramTests extends ElasticsearchIntegrationTest {
assertThat(histo, notNullValue());
assertThat(histo.getName(), equalTo("histo"));
assertThat(histo.getBuckets().size(), equalTo(numValueBuckets));
Object[] propertiesKeys = (Object[]) histo.getProperty("_key");
Object[] propertiesDocCounts = (Object[]) histo.getProperty("_count");
Object[] propertiesCounts = (Object[]) histo.getProperty("sum.value");
List<Histogram.Bucket> buckets = new ArrayList<>(histo.getBuckets());
for (int i = 0; i < numValueBuckets; ++i) {
@ -310,6 +322,9 @@ public class HistogramTests extends ElasticsearchIntegrationTest {
}
}
assertThat(sum.getValue(), equalTo((double) s));
assertThat((String) propertiesKeys[i], equalTo(String.valueOf((long) i * interval)));
assertThat((long) propertiesDocCounts[i], equalTo(valueCounts[i]));
assertThat((double) propertiesCounts[i], equalTo((double) s));
}
}

View File

@ -34,7 +34,10 @@ import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.ipRange;
import static org.elasticsearch.search.aggregations.AggregationBuilders.max;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
@ -227,6 +230,9 @@ public class IPv4RangeTests extends ElasticsearchIntegrationTest {
assertThat(range, notNullValue());
assertThat(range.getName(), equalTo("range"));
assertThat(range.getBuckets().size(), equalTo(3));
Object[] propertiesKeys = (Object[]) range.getProperty("_key");
Object[] propertiesDocCounts = (Object[]) range.getProperty("_count");
Object[] propertiesCounts = (Object[]) range.getProperty("sum.value");
IPv4Range.Bucket bucket = range.getBucketByKey("*-10.0.0.100");
assertThat(bucket, notNullValue());
@ -239,6 +245,9 @@ public class IPv4RangeTests extends ElasticsearchIntegrationTest {
Sum sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getValue(), equalTo((double) 100));
assertThat((String) propertiesKeys[0], equalTo("*-10.0.0.100"));
assertThat((long) propertiesDocCounts[0], equalTo(100l));
assertThat((double) propertiesCounts[0], equalTo((double) 100));
bucket = range.getBucketByKey("10.0.0.100-10.0.0.200");
assertThat(bucket, notNullValue());
@ -251,6 +260,9 @@ public class IPv4RangeTests extends ElasticsearchIntegrationTest {
sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getValue(), equalTo((double) 200));
assertThat((String) propertiesKeys[1], equalTo("10.0.0.100-10.0.0.200"));
assertThat((long) propertiesDocCounts[1], equalTo(100l));
assertThat((double) propertiesCounts[1], equalTo((double) 200));
bucket = range.getBucketByKey("10.0.0.200-*");
assertThat(bucket, notNullValue());
@ -263,6 +275,9 @@ public class IPv4RangeTests extends ElasticsearchIntegrationTest {
sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getValue(), equalTo((double) 55*3));
assertThat((String) propertiesKeys[2], equalTo("10.0.0.200-*"));
assertThat((long) propertiesDocCounts[2], equalTo(55l));
assertThat((double) propertiesCounts[2], equalTo((double) 55 * 3));
}
@Test

View File

@ -36,11 +36,22 @@ import org.hamcrest.Matchers;
import org.junit.Test;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.avg;
import static org.elasticsearch.search.aggregations.AggregationBuilders.extendedStats;
import static org.elasticsearch.search.aggregations.AggregationBuilders.filter;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.max;
import static org.elasticsearch.search.aggregations.AggregationBuilders.stats;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
@ -382,6 +393,9 @@ public class LongTermsTests extends AbstractTermsTests {
assertThat(terms, notNullValue());
assertThat(terms.getName(), equalTo("terms"));
assertThat(terms.getBuckets().size(), equalTo(5));
Object[] propertiesKeys = (Object[]) terms.getProperty("_key");
Object[] propertiesDocCounts = (Object[]) terms.getProperty("_count");
Object[] propertiesCounts = (Object[]) terms.getProperty("sum.value");
for (int i = 0; i < 5; i++) {
Terms.Bucket bucket = terms.getBucketByKey("" + i);
@ -392,6 +406,9 @@ public class LongTermsTests extends AbstractTermsTests {
Sum sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat((long) sum.getValue(), equalTo(i+i+1l));
assertThat((String) propertiesKeys[i], equalTo(String.valueOf(i)));
assertThat((long) propertiesDocCounts[i], equalTo(1l));
assertThat((double) propertiesCounts[i], equalTo((double) i + i + 1l));
}
}

View File

@ -32,7 +32,9 @@ import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.avg;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.missing;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@ -146,6 +148,7 @@ public class MissingTests extends ElasticsearchIntegrationTest {
assertThat(missing, notNullValue());
assertThat(missing.getName(), equalTo("missing_tag"));
assertThat(missing.getDocCount(), equalTo((long) numDocsMissing + numDocsUnmapped));
assertThat((long) missing.getProperty("_count"), equalTo((long) numDocsMissing + numDocsUnmapped));
assertThat(missing.getAggregations().asList().isEmpty(), is(false));
long sum = 0;
@ -159,6 +162,7 @@ public class MissingTests extends ElasticsearchIntegrationTest {
assertThat(avgValue, notNullValue());
assertThat(avgValue.getName(), equalTo("avg_value"));
assertThat(avgValue.getValue(), equalTo((double) sum / (numDocsMissing + numDocsUnmapped)));
assertThat((double) missing.getProperty("avg_value.value"), equalTo((double) sum / (numDocsMissing + numDocsUnmapped)));
}
@Test

View File

@ -18,6 +18,9 @@
*/
package org.elasticsearch.search.aggregations.bucket;
import java.util.ArrayList;
import java.util.List;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
@ -36,16 +39,19 @@ import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.hamcrest.Matchers;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.max;
import static org.elasticsearch.search.aggregations.AggregationBuilders.nested;
import static org.elasticsearch.search.aggregations.AggregationBuilders.stats;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
import static org.hamcrest.core.IsNull.notNullValue;
/**
@ -232,6 +238,7 @@ public class NestedTests extends ElasticsearchIntegrationTest {
assertThat(nested, notNullValue());
assertThat(nested.getName(), equalTo("nested"));
assertThat(nested.getDocCount(), equalTo(docCount));
assertThat((long) nested.getProperty("_count"), equalTo(docCount));
assertThat(nested.getAggregations().asList().isEmpty(), is(false));
LongTerms values = nested.getAggregations().get("values");
@ -249,6 +256,7 @@ public class NestedTests extends ElasticsearchIntegrationTest {
assertEquals(counts[i], bucket.getDocCount());
}
}
assertThat((LongTerms) nested.getProperty("values"), sameInstance(values));
}
@Test

View File

@ -35,7 +35,11 @@ import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.avg;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.range;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@ -268,6 +272,9 @@ public class RangeTests extends ElasticsearchIntegrationTest {
assertThat(range, notNullValue());
assertThat(range.getName(), equalTo("range"));
assertThat(range.getBuckets().size(), equalTo(3));
Object[] propertiesKeys = (Object[]) range.getProperty("_key");
Object[] propertiesDocCounts = (Object[]) range.getProperty("_count");
Object[] propertiesCounts = (Object[]) range.getProperty("sum.value");
Range.Bucket bucket = range.getBucketByKey("*-3.0");
assertThat(bucket, notNullValue());
@ -278,6 +285,9 @@ public class RangeTests extends ElasticsearchIntegrationTest {
Sum sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getValue(), equalTo(3.0)); // 1 + 2
assertThat((String) propertiesKeys[0], equalTo("*-3.0"));
assertThat((long) propertiesDocCounts[0], equalTo(2l));
assertThat((double) propertiesCounts[0], equalTo(3.0));
bucket = range.getBucketByKey("3.0-6.0");
assertThat(bucket, notNullValue());
@ -288,6 +298,9 @@ public class RangeTests extends ElasticsearchIntegrationTest {
sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getValue(), equalTo(12.0)); // 3 + 4 + 5
assertThat((String) propertiesKeys[1], equalTo("3.0-6.0"));
assertThat((long) propertiesDocCounts[1], equalTo(3l));
assertThat((double) propertiesCounts[1], equalTo(12.0));
bucket = range.getBucketByKey("6.0-*");
assertThat(bucket, notNullValue());
@ -302,6 +315,9 @@ public class RangeTests extends ElasticsearchIntegrationTest {
total += i + 1;
}
assertThat(sum.getValue(), equalTo((double) total));
assertThat((String) propertiesKeys[2], equalTo("6.0-*"));
assertThat((long) propertiesDocCounts[2], equalTo(numDocs - 5l));
assertThat((double) propertiesCounts[2], equalTo((double) total));
}
@Test

View File

@ -18,6 +18,10 @@
*/
package org.elasticsearch.search.aggregations.bucket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -28,16 +32,15 @@ import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.nested;
import static org.elasticsearch.search.aggregations.AggregationBuilders.reverseNested;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
import static org.hamcrest.core.IsNull.notNullValue;
/**
@ -155,7 +158,9 @@ public class ReverseNestedTests extends ElasticsearchIntegrationTest {
assertThat(bucket.getKey(), equalTo("1"));
assertThat(bucket.getDocCount(), equalTo(6l));
ReverseNested reverseNested = bucket.getAggregations().get("nested1_to_field1");
assertThat((long) reverseNested.getProperty("_count"), equalTo(5l));
Terms tags = reverseNested.getAggregations().get("field1");
assertThat((Terms) reverseNested.getProperty("field1"), sameInstance(tags));
List<Terms.Bucket> tagsBuckets = new ArrayList<>(tags.getBuckets());
assertThat(tagsBuckets.size(), equalTo(6));
assertThat(tagsBuckets.get(0).getKey(), equalTo("c"));

View File

@ -19,6 +19,7 @@
package org.elasticsearch.search.aggregations.bucket;
import com.google.common.base.Strings;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
@ -41,13 +42,25 @@ import org.junit.Test;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.FilterBuilders.termFilter;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.search.aggregations.AggregationBuilders.avg;
import static org.elasticsearch.search.aggregations.AggregationBuilders.count;
import static org.elasticsearch.search.aggregations.AggregationBuilders.extendedStats;
import static org.elasticsearch.search.aggregations.AggregationBuilders.filter;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.stats;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@ -250,12 +263,16 @@ public class StringTermsTests extends AbstractTermsTests {
assertThat(terms, notNullValue());
assertThat(terms.getName(), equalTo("terms"));
assertThat(terms.getBuckets().size(), equalTo(5));
Object[] propertiesKeys = (Object[]) terms.getProperty("_key");
Object[] propertiesDocCounts = (Object[]) terms.getProperty("_count");
for (int i = 0; i < 5; i++) {
Terms.Bucket bucket = terms.getBucketByKey("val" + i);
assertThat(bucket, notNullValue());
assertThat(key(bucket), equalTo("val" + i));
assertThat(bucket.getDocCount(), equalTo(1l));
assertThat((String) propertiesKeys[i], equalTo("val" + i));
assertThat((long) propertiesDocCounts[i], equalTo(1l));
}
}
@ -631,6 +648,9 @@ public class StringTermsTests extends AbstractTermsTests {
assertThat(terms, notNullValue());
assertThat(terms.getName(), equalTo("terms"));
assertThat(terms.getBuckets().size(), equalTo(5));
Object[] propertiesKeys = (Object[]) terms.getProperty("_key");
Object[] propertiesDocCounts = (Object[]) terms.getProperty("_count");
Object[] propertiesCounts = (Object[]) terms.getProperty("count.value");
for (int i = 0; i < 5; i++) {
Terms.Bucket bucket = terms.getBucketByKey("val" + i);
@ -640,6 +660,9 @@ public class StringTermsTests extends AbstractTermsTests {
ValueCount valueCount = bucket.getAggregations().get("count");
assertThat(valueCount, notNullValue());
assertThat(valueCount.getValue(), equalTo(2l));
assertThat((String) propertiesKeys[i], equalTo("val" + i));
assertThat((long) propertiesDocCounts[i], equalTo(1l));
assertThat((double) propertiesCounts[i], equalTo(2.0));
}
}

View File

@ -29,6 +29,7 @@ import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregator.SubAggCollectionMode;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.nested.Nested;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
@ -49,13 +50,26 @@ import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.common.xcontent.XContentFactory.smileBuilder;
import static org.elasticsearch.common.xcontent.XContentFactory.yamlBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.index.query.QueryBuilders.nestedQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.hamcrest.core.IsNull.nullValue;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.max;
import static org.elasticsearch.search.aggregations.AggregationBuilders.nested;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.search.aggregations.AggregationBuilders.topHits;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.emptyArray;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
/**
*
@ -255,6 +269,26 @@ public class TopHitsTests extends ElasticsearchIntegrationTest {
}
}
@Test
public void testBasics_getProperty() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(global("global").subAggregation(topHits("hits"))).execute().actionGet();
assertSearchResponse(searchResponse);
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
TopHits topHits = global.getAggregations().get("hits");
assertThat(topHits, notNullValue());
assertThat(topHits.getName(), equalTo("hits"));
assertThat((TopHits) global.getProperty("hits"), sameInstance(topHits));
}
@Test
public void testPagination() throws Exception {
int size = randomIntBetween(1, 10);

View File

@ -77,6 +77,8 @@ public abstract class AbstractNumericTests extends ElasticsearchIntegrationTest
public abstract void testSingleValuedField() throws Exception;
public abstract void testSingleValuedField_getProperty() throws Exception;
public abstract void testSingleValuedField_PartiallyUnmapped() throws Exception;
public abstract void testSingleValuedField_WithValueScript() throws Exception;

View File

@ -19,6 +19,7 @@
package org.elasticsearch.search.aggregations.metrics;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.metrics.avg.Avg;
import org.elasticsearch.test.junit.annotations.TestLogging;
@ -26,8 +27,11 @@ import org.junit.Test;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.avg;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
/**
*
@ -84,6 +88,31 @@ public class AvgTests extends AbstractNumericTests {
assertThat(avg.getValue(), equalTo((double) (1+2+3+4+5+6+7+8+9+10) / 10));
}
@Test
public void testSingleValuedField_getProperty() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(global("global").subAggregation(avg("avg").field("value"))).execute().actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(10l));
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getDocCount(), equalTo(10l));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
Avg avg = global.getAggregations().get("avg");
assertThat(avg, notNullValue());
assertThat(avg.getName(), equalTo("avg"));
double expectedAvgValue = (double) (1+2+3+4+5+6+7+8+9+10) / 10;
assertThat(avg.getValue(), equalTo(expectedAvgValue));
assertThat((Avg) global.getProperty("avg"), equalTo(avg));
assertThat((double) global.getProperty("avg.value"), equalTo(expectedAvgValue));
assertThat((double) avg.getProperty("value"), equalTo(expectedAvgValue));
}
@Override
public void testSingleValuedField_PartiallyUnmapped() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx", "idx_unmapped")

View File

@ -24,18 +24,21 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.search.aggregations.Aggregator.SubAggCollectionMode;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.cardinality.Cardinality;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.cardinality;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.hamcrest.Matchers.notNullValue;
@ElasticsearchIntegrationTest.SuiteScopeTest
public class CardinalityTests extends ElasticsearchIntegrationTest {
@ -220,6 +223,34 @@ public class CardinalityTests extends ElasticsearchIntegrationTest {
assertCount(count, numDocs);
}
@Test
public void singleValuedNumeric_getProperty() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(
global("global").subAggregation(
cardinality("cardinality").precisionThreshold(precisionThreshold).field(singleNumericField(false))))
.execute().actionGet();
assertSearchResponse(searchResponse);
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
// assertThat(global.getDocCount(), equalTo(numDocs));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
Cardinality cardinality = global.getAggregations().get("cardinality");
assertThat(cardinality, notNullValue());
assertThat(cardinality.getName(), equalTo("cardinality"));
long expectedValue = numDocs;
assertCount(cardinality, expectedValue);
assertThat((Cardinality) global.getProperty("cardinality"), equalTo(cardinality));
assertThat((double) global.getProperty("cardinality.value"), equalTo((double) cardinality.getValue()));
assertThat((double) cardinality.getProperty("value"), equalTo((double) cardinality.getValue()));
}
@Test
public void singleValuedNumericHashed() throws Exception {
SearchResponse response = client().prepareSearch("idx").setTypes("type")

View File

@ -20,14 +20,19 @@ package org.elasticsearch.search.aggregations.metrics;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.metrics.stats.extended.ExtendedStats;
import org.junit.Test;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.extendedStats;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.sameInstance;
/**
*
@ -118,6 +123,53 @@ public class ExtendedStatsTests extends AbstractNumericTests {
assertThat(stats.getStdDeviation(), equalTo(stdDev(1, 2, 3, 4, 5, 6, 7, 8 ,9, 10)));
}
@Test
public void testSingleValuedField_getProperty() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(global("global").subAggregation(extendedStats("stats").field("value"))).execute().actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(10l));
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getDocCount(), equalTo(10l));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
ExtendedStats stats = global.getAggregations().get("stats");
assertThat(stats, notNullValue());
assertThat(stats.getName(), equalTo("stats"));
ExtendedStats statsFromProperty = (ExtendedStats) global.getProperty("stats");
assertThat(statsFromProperty, notNullValue());
assertThat(statsFromProperty, sameInstance(stats));
double expectedAvgValue = (double) (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10) / 10;
assertThat(stats.getAvg(), equalTo(expectedAvgValue));
assertThat((double) global.getProperty("stats.avg"), equalTo(expectedAvgValue));
double expectedMinValue = 1.0;
assertThat(stats.getMin(), equalTo(expectedMinValue));
assertThat((double) global.getProperty("stats.min"), equalTo(expectedMinValue));
double expectedMaxValue = 10.0;
assertThat(stats.getMax(), equalTo(expectedMaxValue));
assertThat((double) global.getProperty("stats.max"), equalTo(expectedMaxValue));
double expectedSumValue = (double) (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10);
assertThat(stats.getSum(), equalTo(expectedSumValue));
assertThat((double) global.getProperty("stats.sum"), equalTo(expectedSumValue));
long expectedCountValue = 10;
assertThat(stats.getCount(), equalTo(expectedCountValue));
assertThat((double) global.getProperty("stats.count"), equalTo((double) expectedCountValue));
double expectedSumOfSquaresValue = (double) 1 + 4 + 9 + 16 + 25 + 36 + 49 + 64 + 81 + 100;
assertThat(stats.getSumOfSquares(), equalTo(expectedSumOfSquaresValue));
assertThat((double) global.getProperty("stats.sum_of_squares"), equalTo(expectedSumOfSquaresValue));
double expectedVarianceValue = variance(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
assertThat(stats.getVariance(), equalTo(expectedVarianceValue));
assertThat((double) global.getProperty("stats.variance"), equalTo(expectedVarianceValue));
double expectedStdDevValue = stdDev(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
assertThat(stats.getStdDeviation(), equalTo(expectedStdDevValue));
assertThat((double) global.getProperty("stats.std_deviation"), equalTo(expectedStdDevValue));
}
@Test
public void testSingleValuedField_PartiallyUnmapped() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx", "idx_unmapped")

View File

@ -29,6 +29,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket;
import org.elasticsearch.search.aggregations.metrics.geobounds.GeoBounds;
@ -45,11 +46,13 @@ import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.geoBounds;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.sameInstance;
/**
*
@ -219,6 +222,40 @@ public class GeoBoundsTests extends ElasticsearchIntegrationTest {
assertThat(bottomRight.lon(), equalTo(singleBottomRight.lon()));
}
@Test
public void testSingleValuedField_getProperty() throws Exception {
SearchResponse searchResponse = client()
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
global("global").subAggregation(geoBounds("geoBounds").field(SINGLE_VALUED_FIELD_NAME).wrapLongitude(false)))
.execute().actionGet();
assertSearchResponse(searchResponse);
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getDocCount(), equalTo((long) numDocs));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
GeoBounds geobounds = global.getAggregations().get("geoBounds");
assertThat(geobounds, notNullValue());
assertThat(geobounds.getName(), equalTo("geoBounds"));
assertThat((GeoBounds) global.getProperty("geoBounds"), sameInstance(geobounds));
GeoPoint topLeft = geobounds.topLeft();
GeoPoint bottomRight = geobounds.bottomRight();
assertThat(topLeft.lat(), equalTo(singleTopLeft.lat()));
assertThat(topLeft.lon(), equalTo(singleTopLeft.lon()));
assertThat(bottomRight.lat(), equalTo(singleBottomRight.lat()));
assertThat(bottomRight.lon(), equalTo(singleBottomRight.lon()));
assertThat((double) global.getProperty("geoBounds.top"), equalTo(singleTopLeft.lat()));
assertThat((double) global.getProperty("geoBounds.left"), equalTo(singleTopLeft.lon()));
assertThat((double) global.getProperty("geoBounds.bottom"), equalTo(singleBottomRight.lat()));
assertThat((double) global.getProperty("geoBounds.right"), equalTo(singleBottomRight.lon()));
}
@Test
public void multiValuedField() throws Exception {
SearchResponse response = client().prepareSearch("idx")

View File

@ -19,11 +19,13 @@
package org.elasticsearch.search.aggregations.metrics;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.metrics.max.Max;
import org.junit.Test;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.max;
import static org.hamcrest.Matchers.equalTo;
@ -84,6 +86,30 @@ public class MaxTests extends AbstractNumericTests {
assertThat(max.getValue(), equalTo(10.0));
}
@Test
public void testSingleValuedField_getProperty() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(global("global").subAggregation(max("max").field("value"))).execute().actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(10l));
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getDocCount(), equalTo(10l));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
Max max = global.getAggregations().get("max");
assertThat(max, notNullValue());
assertThat(max.getName(), equalTo("max"));
double expectedMaxValue = 10.0;
assertThat(max.getValue(), equalTo(expectedMaxValue));
assertThat((Max) global.getProperty("max"), equalTo(max));
assertThat((double) global.getProperty("max.value"), equalTo(expectedMaxValue));
assertThat((double) max.getProperty("value"), equalTo(expectedMaxValue));
}
@Test
public void testSingleValuedField_PartiallyUnmapped() throws Exception {

View File

@ -19,11 +19,13 @@
package org.elasticsearch.search.aggregations.metrics;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.metrics.min.Min;
import org.junit.Test;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.min;
import static org.hamcrest.Matchers.equalTo;
@ -84,6 +86,31 @@ public class MinTests extends AbstractNumericTests {
assertThat(min.getValue(), equalTo(1.0));
}
@Test
public void testSingleValuedField_getProperty() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(global("global").subAggregation(min("min").field("value"))).execute().actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(10l));
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getDocCount(), equalTo(10l));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
Min min = global.getAggregations().get("min");
assertThat(min, notNullValue());
assertThat(min.getName(), equalTo("min"));
double expectedMinValue = 1.0;
assertThat(min.getValue(), equalTo(expectedMinValue));
assertThat((Min) global.getProperty("min"), equalTo(min));
assertThat((double) global.getProperty("min.value"), equalTo(expectedMinValue));
assertThat((double) min.getProperty("value"), equalTo(expectedMinValue));
}
@Test
public void testSingleValuedField_PartiallyUnmapped() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx", "idx_unmapped")

View File

@ -21,6 +21,7 @@ package org.elasticsearch.search.aggregations.metrics;
import com.google.common.collect.Lists;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram.Order;
import org.elasticsearch.search.aggregations.metrics.percentiles.Percentile;
@ -32,9 +33,14 @@ import java.util.Arrays;
import java.util.List;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.percentileRanks;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.sameInstance;
/**
*
@ -151,6 +157,33 @@ public class PercentileRanksTests extends AbstractNumericTests {
assertConsistent(pcts, percentiles, minValue, maxValue);
}
@Test
public void testSingleValuedField_getProperty() throws Exception {
final double[] pcts = randomPercents(minValue, maxValue);
SearchResponse searchResponse = client()
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
global("global").subAggregation(
randomCompression(percentileRanks("percentile_ranks")).field("value").percentiles(pcts))).execute()
.actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(10l));
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getDocCount(), equalTo(10l));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
PercentileRanks percentiles = global.getAggregations().get("percentile_ranks");
assertThat(percentiles, notNullValue());
assertThat(percentiles.getName(), equalTo("percentile_ranks"));
assertThat((PercentileRanks) global.getProperty("percentile_ranks"), sameInstance(percentiles));
}
@Test
public void testSingleValuedFieldOutsideRange() throws Exception {
final double[] pcts = new double[] {minValue - 1, maxValue + 1};

View File

@ -21,6 +21,7 @@ package org.elasticsearch.search.aggregations.metrics;
import com.google.common.collect.Lists;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram.Order;
import org.elasticsearch.search.aggregations.metrics.percentiles.Percentile;
@ -32,9 +33,14 @@ import java.util.Arrays;
import java.util.List;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.percentiles;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.sameInstance;
/**
*
@ -75,14 +81,15 @@ public class PercentilesTests extends AbstractNumericTests {
for (int i = 0; i < pcts.length; ++i) {
final Percentile percentile = percentileList.get(i);
assertThat(percentile.getPercent(), equalTo(pcts[i]));
assertThat(percentile.getValue(), greaterThanOrEqualTo((double) minValue));
assertThat(percentile.getValue(), lessThanOrEqualTo((double) maxValue));
double value = percentile.getValue();
assertThat(value, greaterThanOrEqualTo((double) minValue));
assertThat(value, lessThanOrEqualTo((double) maxValue));
if (percentile.getPercent() == 0) {
assertThat(percentile.getValue(), equalTo((double) minValue));
assertThat(value, equalTo((double) minValue));
}
if (percentile.getPercent() == 100) {
assertThat(percentile.getValue(), equalTo((double) maxValue));
assertThat(value, equalTo((double) maxValue));
}
}
@ -150,6 +157,32 @@ public class PercentilesTests extends AbstractNumericTests {
assertConsistent(pcts, percentiles, minValue, maxValue);
}
@Test
public void testSingleValuedField_getProperty() throws Exception {
final double[] pcts = randomPercentiles();
SearchResponse searchResponse = client()
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
global("global").subAggregation(randomCompression(percentiles("percentiles")).field("value").percentiles(pcts)))
.execute().actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(10l));
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getDocCount(), equalTo(10l));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
Percentiles percentiles = global.getAggregations().get("percentiles");
assertThat(percentiles, notNullValue());
assertThat(percentiles.getName(), equalTo("percentiles"));
assertThat((Percentiles) global.getProperty("percentiles"), sameInstance(percentiles));
}
@Test
public void testSingleValuedField_PartiallyUnmapped() throws Exception {
final double[] pcts = randomPercentiles();

View File

@ -19,11 +19,6 @@
package org.elasticsearch.search.aggregations.metrics;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptResponse;
import org.elasticsearch.action.search.SearchResponse;
@ -31,6 +26,7 @@ import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram.Bucket;
import org.elasticsearch.search.aggregations.metrics.scripted.ScriptedMetric;
@ -39,8 +35,14 @@ import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.scriptedMetric;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
@ -52,6 +54,7 @@ import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
@ClusterScope(scope = Scope.SUITE)
@ElasticsearchIntegrationTest.SuiteScopeTest
@ -139,12 +142,12 @@ public class ScriptedMetricTests extends ElasticsearchIntegrationTest {
Map<String, Object> map = (Map<String, Object>) object;
assertThat(map.size(), lessThanOrEqualTo(1));
if (map.size() == 1) {
assertThat(map.get("count"), notNullValue());
assertThat(map.get("count"), instanceOf(Number.class));
assertThat((Number) map.get("count"), equalTo((Number) 1));
assertThat(map.get("count"), notNullValue());
assertThat(map.get("count"), instanceOf(Number.class));
assertThat((Number) map.get("count"), equalTo((Number) 1));
numShardsRun++;
}
}
}
// We don't know how many shards will have documents but we need to make
// sure that at least one shard ran the map script
assertThat(numShardsRun, greaterThan(0));
@ -365,6 +368,57 @@ public class ScriptedMetricTests extends ElasticsearchIntegrationTest {
assertThat(((Number) object).longValue(), equalTo(numDocs * 3));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testInitMapCombineReduce_getProperty() throws Exception {
Map<String, Object> varsMap = new HashMap<>();
varsMap.put("multiplier", 1);
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
SearchResponse searchResponse = client()
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
global("global")
.subAggregation(
scriptedMetric("scripted")
.params(params)
.initScript("vars.multiplier = 3")
.mapScript("_agg.add(vars.multiplier)")
.combineScript(
"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation")
.reduceScript(
"newaggregation = []; sum = 0;for (aggregation in _aggs) { for (a in aggregation) { sum += a} }; newaggregation.add(sum); return newaggregation")))
.execute().actionGet();
assertSearchResponse(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(numDocs));
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getDocCount(), equalTo(numDocs));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
ScriptedMetric scriptedMetricAggregation = global.getAggregations().get("scripted");
assertThat(scriptedMetricAggregation, notNullValue());
assertThat(scriptedMetricAggregation.getName(), equalTo("scripted"));
assertThat(scriptedMetricAggregation.aggregation(), notNullValue());
assertThat(scriptedMetricAggregation.aggregation(), instanceOf(ArrayList.class));
List<?> aggregationList = (List<?>) scriptedMetricAggregation.aggregation();
assertThat(aggregationList.size(), equalTo(1));
Object object = aggregationList.get(0);
assertThat(object, notNullValue());
assertThat(object, instanceOf(Number.class));
assertThat(((Number) object).longValue(), equalTo(numDocs * 3));
assertThat((ScriptedMetric) global.getProperty("scripted"), sameInstance(scriptedMetricAggregation));
assertThat((List) global.getProperty("scripted.value"), sameInstance((List) aggregationList));
assertThat((List) scriptedMetricAggregation.getProperty("value"), sameInstance((List) aggregationList));
}
@Test
public void testMapCombineReduce_withParams() {
Map<String, Object> varsMap = new HashMap<>();

View File

@ -20,15 +20,20 @@ package org.elasticsearch.search.aggregations.metrics;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.metrics.stats.Stats;
import org.elasticsearch.test.junit.annotations.TestLogging;
import org.junit.Test;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.stats;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.sameInstance;
/**
*
@ -103,6 +108,44 @@ public class StatsTests extends AbstractNumericTests {
assertThat(stats.getCount(), equalTo(10l));
}
@Test
public void testSingleValuedField_getProperty() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(global("global").subAggregation(stats("stats").field("value"))).execute().actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(10l));
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getDocCount(), equalTo(10l));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
Stats stats = global.getAggregations().get("stats");
assertThat(stats, notNullValue());
assertThat(stats.getName(), equalTo("stats"));
Stats statsFromProperty = (Stats) global.getProperty("stats");
assertThat(statsFromProperty, notNullValue());
assertThat(statsFromProperty, sameInstance(stats));
double expectedAvgValue = (double) (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10) / 10;
assertThat(stats.getAvg(), equalTo(expectedAvgValue));
assertThat((double) global.getProperty("stats.avg"), equalTo(expectedAvgValue));
double expectedMinValue = 1.0;
assertThat(stats.getMin(), equalTo(expectedMinValue));
assertThat((double) global.getProperty("stats.min"), equalTo(expectedMinValue));
double expectedMaxValue = 10.0;
assertThat(stats.getMax(), equalTo(expectedMaxValue));
assertThat((double) global.getProperty("stats.max"), equalTo(expectedMaxValue));
double expectedSumValue = (double) (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10);
assertThat(stats.getSum(), equalTo(expectedSumValue));
assertThat((double) global.getProperty("stats.sum"), equalTo(expectedSumValue));
long expectedCountValue = 10;
assertThat(stats.getCount(), equalTo(expectedCountValue));
assertThat((double) global.getProperty("stats.count"), equalTo((double) expectedCountValue));
}
@Test
public void testSingleValuedField_PartiallyUnmapped() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx", "idx_unmapped")

View File

@ -19,11 +19,13 @@
package org.elasticsearch.search.aggregations.metrics;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.junit.Test;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.hamcrest.Matchers.equalTo;
@ -84,6 +86,31 @@ public class SumTests extends AbstractNumericTests {
assertThat(sum.getValue(), equalTo((double) 1+2+3+4+5+6+7+8+9+10));
}
@Test
public void testSingleValuedField_getProperty() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(global("global").subAggregation(sum("sum").field("value"))).execute().actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(10l));
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getDocCount(), equalTo(10l));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
Sum sum = global.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getName(), equalTo("sum"));
double expectedSumValue = (double) 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10;
assertThat(sum.getValue(), equalTo(expectedSumValue));
assertThat((Sum) global.getProperty("sum"), equalTo(sum));
assertThat((double) global.getProperty("sum.value"), equalTo(expectedSumValue));
assertThat((double) sum.getProperty("value"), equalTo(expectedSumValue));
}
@Override
public void testSingleValuedField_PartiallyUnmapped() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx", "idx_unmapped")

View File

@ -19,6 +19,7 @@
package org.elasticsearch.search.aggregations.metrics;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
@ -26,6 +27,7 @@ import org.junit.Test;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.count;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
@ -83,6 +85,30 @@ public class ValueCountTests extends ElasticsearchIntegrationTest {
assertThat(valueCount.getValue(), equalTo(10l));
}
@Test
public void singleValuedField_getProperty() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(global("global").subAggregation(count("count").field("value"))).execute().actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(10l));
Global global = searchResponse.getAggregations().get("global");
assertThat(global, notNullValue());
assertThat(global.getName(), equalTo("global"));
assertThat(global.getDocCount(), equalTo(10l));
assertThat(global.getAggregations(), notNullValue());
assertThat(global.getAggregations().asMap().size(), equalTo(1));
ValueCount valueCount = global.getAggregations().get("count");
assertThat(valueCount, notNullValue());
assertThat(valueCount.getName(), equalTo("count"));
assertThat(valueCount.getValue(), equalTo(10l));
assertThat((ValueCount) global.getProperty("count"), equalTo(valueCount));
assertThat((double) global.getProperty("count.value"), equalTo(10d));
assertThat((double) valueCount.getProperty("value"), equalTo(10d));
}
@Test
public void singleValuedField_PartiallyUnmapped() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx", "idx_unmapped")

View File

@ -58,7 +58,7 @@ public class PathTests extends ElasticsearchTestCase {
private void assertInvalidPath(String path, String reason) {
try {
OrderPath.parse(path);
AggregationPath.parse(path);
fail("Expected parsing path [" + path + "] to fail - " + reason);
} catch (AggregationExecutionException aee) {
// expected
@ -66,12 +66,12 @@ public class PathTests extends ElasticsearchTestCase {
}
private void assertValidPath(String path, Tokens tokenz) {
OrderPath.Token[] tokens = tokenz.toArray();
OrderPath p = OrderPath.parse(path);
assertThat(p.tokens.length, equalTo(tokens.length));
for (int i = 0; i < p.tokens.length; i++) {
OrderPath.Token t1 = p.tokens[i];
OrderPath.Token t2 = tokens[i];
AggregationPath.PathElement[] tokens = tokenz.toArray();
AggregationPath p = AggregationPath.parse(path);
assertThat(p.getPathElements().size(), equalTo(tokens.length));
for (int i = 0; i < p.getPathElements().size(); i++) {
AggregationPath.PathElement t1 = p.getPathElements().get(i);
AggregationPath.PathElement t2 = tokens[i];
assertThat(t1, equalTo(t2));
}
}
@ -82,24 +82,24 @@ public class PathTests extends ElasticsearchTestCase {
private static class Tokens {
private List<OrderPath.Token> tokens = new ArrayList<>();
private List<AggregationPath.PathElement> tokens = new ArrayList<>();
Tokens add(String name) {
tokens.add(new OrderPath.Token(name, name, null));
tokens.add(new AggregationPath.PathElement(name, name, null));
return this;
}
Tokens add(String name, String key) {
if (Math.random() > 0.5) {
tokens.add(new OrderPath.Token(name + "." + key, name, key));
tokens.add(new AggregationPath.PathElement(name + "." + key, name, key));
} else {
tokens.add(new OrderPath.Token(name + "[" + key + "]", name, key));
tokens.add(new AggregationPath.PathElement(name + "[" + key + "]", name, key));
}
return this;
}
OrderPath.Token[] toArray() {
return tokens.toArray(new OrderPath.Token[tokens.size()]);
AggregationPath.PathElement[] toArray() {
return tokens.toArray(new AggregationPath.PathElement[tokens.size()]);
}