# Springdata elasticsearch 5.2 nested aggregation without subAggregation

**URL:** <https://discuss.elastic.co/t/springdata-elasticsearch-5-2-nested-aggregation-without-subaggregation/362052>\
**Category:** Elasticsearch\
**Tags:** language-clients\
**Created:** [June 25, 2024, 8:47pm UTC](https://discuss.elastic.co/t/springdata-elasticsearch-5-2-nested-aggregation-without-subaggregation/362052 "2024-06-25T20:47:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![thVlm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/thvlm/32/135561_2.png) [@thVlm](https://discuss.elastic.co/u/thVlm)\
**Post date:** [June 25, 2024, 8:47pm UTC](https://discuss.elastic.co/t/springdata-elasticsearch-5-2-nested-aggregation-without-subaggregation/362052/1 "2024-06-25T20:47:42Z")

</div>

## Help Needed: Nested Aggregations with Java API Client v8

I'm working on a project using Elasticsearch with the Java API Client v8, and I'm struggling to correctly implement nested aggregations. I'd greatly appreciate any help or guidance.

### Index Mapping

Here's the relevant part of my index mapping:

```auto
{
  "actions" : {
    "mappings" : {
      "properties" : {
        "actionRoles" : {
          "type" : "nested",
          "properties" : {
            "roleName" : {
              "type" : "keyword"
            }
          }
        },
        // ... other fields ...
      }
    }
  }
}

```

I need to find out how to make this TODO

```kotlin
fun toNativeQuery(): NativeQuery {
        val criteriaQuery = CriteriaQuery(criteria)
        val queryBuilder = NativeQuery.builder().withQuery(criteriaQuery)
        //...
            
        queryBuilder.withAggregation(
            AGG_ACTION_ROLE,
            //TODO: Add the nested aggregation for 'actionRoles.roleName'
            
        )
        //...
        return queryBuilder.build()
    }

```

I should be able to get this aggregation generated, which is working in Kibana

```auto
{
  "aggregations": {
    "actionRoles": {
      "nested": {
        "path": "actionRoles"
      },
      "aggregations": {
        "roleNames": {
          "terms": {
            "field": "actionRoles.roleName",
            "size": 1000
          }
        }
      }
    }
  }

```

Since subAggregation has been removed in elasticsearch-rest-client 8, I couldn't make it work for now.

I guess I have to do something like

```auto
queryBuilder.withAggregation(
            AGG_ACTION_ROLE,
            //TODO: Add the nested aggregation for 'actionRoles'
            AggregationBuilders.nested {
                //how to do the nested aggregation here?
            }
        ) 

```

Any ideas guys? Thanks a lot!

---

<div class="post-metadata">

**Author:** ![ltrotta](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ltrotta/32/124003_2.png) [@ltrotta](https://discuss.elastic.co/u/ltrotta)\
**Post date:** [June 26, 2024, 7:39am UTC](https://discuss.elastic.co/t/springdata-elasticsearch-5-2-nested-aggregation-without-subaggregation/362052/2 "2024-06-26T07:39:32Z")

</div>

Hello and welcome! Not sure about spring data, but using the elasticsearch-java client here's how that nested aggregation with a sub aggregation should be written:

```auto
esClient.search(s -> s
    .index("my-index")
    .aggregations("actionRoles", a -> a.nested(n -> n.path("actionRoles"))
        .aggregations("roleNames", subAgg -> subAgg
            .terms(t -> t.field("actionRoles.roleName")
            .size(1000))))
    , Object.class);

```

---

<div class="post-metadata">

**Author:** ![thVlm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/thvlm/32/135561_2.png) [@thVlm](https://discuss.elastic.co/u/thVlm)\
**Post date:** [June 26, 2024, 7:56am UTC](https://discuss.elastic.co/t/springdata-elasticsearch-5-2-nested-aggregation-without-subaggregation/362052/3 "2024-06-26T07:56:22Z")

</div>

Thanks @ltrotta for your answer,  
Yes I saw that already but I must stick with Springdata and NativeQuery.

The closest I could do is the following:

kotlin

```auto
        queryBuilder.withAggregation(
            AGG_ACTION_ROLE,
            //TODO: Add the nested aggregation for 'actionRoles'
            AggregationBuilders.nested { nestedAgg: NestedAggregation.Builder ->
                nestedAgg.path(ActionEntity::actionRoles.name)
            },
        )

```

But it is incomplete and I can't get the result I need. I just get a count of the number of actionRoles with that.

---

<div class="post-metadata">

**Author:** ![ltrotta](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ltrotta/32/124003_2.png) [@ltrotta](https://discuss.elastic.co/u/ltrotta)\
**Post date:** [June 26, 2024, 8:12am UTC](https://discuss.elastic.co/t/springdata-elasticsearch-5-2-nested-aggregation-without-subaggregation/362052/4 "2024-06-26T08:12:03Z")

</div>

In this case I'd suggest contacting the owners of spring-data-elasticsearch, it's a separate project which we're not really familiar with.

---

<div class="post-metadata">

**Author:** ![thVlm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/thvlm/32/135561_2.png) [@thVlm](https://discuss.elastic.co/u/thVlm)\
**Post date:** [June 27, 2024, 9:58am UTC](https://discuss.elastic.co/t/springdata-elasticsearch-5-2-nested-aggregation-without-subaggregation/362052/5 "2024-06-27T09:58:40Z")

</div>

In case it might help someone, my tech lead could help and provided this solution that is indeed working

```auto
fun toNativeQuery(): NativeQuery {
            val criteriaQuery = CriteriaQuery(criteria)
            val queryBuilder = NativeQuery.builder().withQuery(criteriaQuery)
            //...
    
            val subAggRoleName =
            AggregationBuilders.terms { it.field("${ActionEntity::actionRoles.name}.${ActionRoleEntity::roleName.name}") }
            // AggregationBuilder.nested does support sub-aggregations,
            // so we need to build it with the Aggregation.Builder()
            val aggNestedActionRolesName =
            Aggregation
                .Builder()
                .nested { it.path(ActionEntity::actionRoles.name) }
                .aggregations(
                    mapOf("roleNames" to subAggRoleName),
                ).build()
            queryBuilder.withAggregation(AGG_ACTION_ROLE, aggNestedActionRolesName)

            //...
            return queryBuilder.build()
}

```
