elasticsearchspring-data-elasticsearchelasticsearch-aggregationnativequeryelasticsearch-rest-client

Elasticsearch Nested Aggregations with Spring data elasticsearch 5.2


Help Needed: Perform a Nested Aggregation with Spring Data Elasticsearch 5.2.6 and Elasticsearch-rest-client 8.10 I'm working on a project using Elasticsearch with Spring Data Elasticsearch 5.2.6, 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:

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

I need to find out how to make this TODO

    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

    {
      "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

    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!


Solution

  • As my tech lead could help and provided this solution that is indeed working

    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()
    }