public void testEmptyAggregation() throws Exception {
    SearchResponse searchResponse =
        client()
            .prepareSearch("empty_bucket_idx")
            .setQuery(matchAllQuery())
            .addAggregation(
                histogram("histo")
                    .field("value")
                    .interval(1L)
                    .minDocCount(0)
                    .subAggregation(nested("nested", "nested")))
            .execute()
            .actionGet();

    assertThat(searchResponse.getHits().getTotalHits(), equalTo(2L));
    Histogram histo = searchResponse.getAggregations().get("histo");
    assertThat(histo, Matchers.notNullValue());
    Histogram.Bucket bucket = histo.getBuckets().get(1);
    assertThat(bucket, Matchers.notNullValue());

    Nested nested = bucket.getAggregations().get("nested");
    assertThat(nested, Matchers.notNullValue());
    assertThat(nested.getName(), equalTo("nested"));
    assertThat(nested.getDocCount(), is(0L));
  }
  public void testNestedWithSubTermsAgg() throws Exception {
    SearchResponse response =
        client()
            .prepareSearch("idx")
            .addAggregation(
                nested("nested", "nested")
                    .subAggregation(
                        terms("values")
                            .field("nested.value")
                            .size(100)
                            .collectMode(aggCollectionMode)))
            .execute()
            .actionGet();

    assertSearchResponse(response);

    long docCount = 0;
    long[] counts = new long[numParents + 6];
    for (int i = 0; i < numParents; ++i) {
      for (int j = 0; j < numChildren[i]; ++j) {
        final int value = i + 1 + j;
        ++counts[value];
        ++docCount;
      }
    }
    int uniqueValues = 0;
    for (long count : counts) {
      if (count > 0) {
        ++uniqueValues;
      }
    }

    Nested nested = response.getAggregations().get("nested");
    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");
    assertThat(values, notNullValue());
    assertThat(values.getName(), equalTo("values"));
    assertThat(values.getBuckets(), notNullValue());
    assertThat(values.getBuckets().size(), equalTo(uniqueValues));
    for (int i = 0; i < counts.length; ++i) {
      final String key = Long.toString(i);
      if (counts[i] == 0) {
        assertNull(values.getBucketByKey(key));
      } else {
        Bucket bucket = values.getBucketByKey(key);
        assertNotNull(bucket);
        assertEquals(counts[i], bucket.getDocCount());
      }
    }
    assertThat((LongTerms) nested.getProperty("values"), sameInstance(values));
  }
  public void testNonExistingNestedField() throws Exception {
    SearchResponse searchResponse =
        client()
            .prepareSearch("idx")
            .addAggregation(
                nested("nested", "value")
                    .subAggregation(stats("nested_value_stats").field("nested.value")))
            .execute()
            .actionGet();

    Nested nested = searchResponse.getAggregations().get("nested");
    assertThat(nested, Matchers.notNullValue());
    assertThat(nested.getName(), equalTo("nested"));
    assertThat(nested.getDocCount(), is(0L));
  }
  public void testSimple() throws Exception {
    SearchResponse response =
        client()
            .prepareSearch("idx")
            .addAggregation(
                nested("nested", "nested")
                    .subAggregation(stats("nested_value_stats").field("nested.value")))
            .execute()
            .actionGet();

    assertSearchResponse(response);

    double min = Double.POSITIVE_INFINITY;
    double max = Double.NEGATIVE_INFINITY;
    long sum = 0;
    long count = 0;
    for (int i = 0; i < numParents; ++i) {
      for (int j = 0; j < numChildren[i]; ++j) {
        final long value = i + 1 + j;
        min = Math.min(min, value);
        max = Math.max(max, value);
        sum += value;
        ++count;
      }
    }

    Nested nested = response.getAggregations().get("nested");
    assertThat(nested, notNullValue());
    assertThat(nested.getName(), equalTo("nested"));
    assertThat(nested.getDocCount(), equalTo(count));
    assertThat(nested.getAggregations().asList().isEmpty(), is(false));

    Stats stats = nested.getAggregations().get("nested_value_stats");
    assertThat(stats, notNullValue());
    assertThat(stats.getMin(), equalTo(min));
    assertThat(stats.getMax(), equalTo(max));
    assertThat(stats.getCount(), equalTo(count));
    assertThat(stats.getSum(), equalTo((double) sum));
    assertThat(stats.getAvg(), equalTo((double) sum / count));
  }
  public void testNestNestedAggs() throws Exception {
    SearchResponse response =
        client()
            .prepareSearch("idx_nested_nested_aggs")
            .addAggregation(
                nested("level1", "nested1")
                    .subAggregation(
                        terms("a")
                            .field("nested1.a")
                            .collectMode(aggCollectionMode)
                            .subAggregation(
                                nested("level2", "nested1.nested2")
                                    .subAggregation(sum("sum").field("nested1.nested2.b")))))
            .get();
    assertSearchResponse(response);

    Nested level1 = response.getAggregations().get("level1");
    assertThat(level1, notNullValue());
    assertThat(level1.getName(), equalTo("level1"));
    assertThat(level1.getDocCount(), equalTo(2L));

    StringTerms a = level1.getAggregations().get("a");
    Terms.Bucket bBucket = a.getBucketByKey("a");
    assertThat(bBucket.getDocCount(), equalTo(1L));

    Nested level2 = bBucket.getAggregations().get("level2");
    assertThat(level2.getDocCount(), equalTo(1L));
    Sum sum = level2.getAggregations().get("sum");
    assertThat(sum.getValue(), equalTo(2d));

    a = level1.getAggregations().get("a");
    bBucket = a.getBucketByKey("b");
    assertThat(bBucket.getDocCount(), equalTo(1L));

    level2 = bBucket.getAggregations().get("level2");
    assertThat(level2.getDocCount(), equalTo(1L));
    sum = level2.getAggregations().get("sum");
    assertThat(sum.getValue(), equalTo(2d));
  }