Home > Blockchain >  How to map Elasticsearch Spring Data AggregationsContainer contents to custom model?
How to map Elasticsearch Spring Data AggregationsContainer contents to custom model?

Time:12-30

I am using Elsaticsearch Spring Data. I have a custom repository that uses ElasticsearchOperations based on examples on docs. I need some aggregation query results and I successfully get the intended results. but I need to map those results to a model. But currently I'm unable to access contents of AggregationsContainer.

 override fun getStats(startTime: Long, endTime: Long, pageable: Pageable): AggregationsContainer<*>? 
    {
        val query: Query = NativeSearchQueryBuilder()
            .withQuery(QueryBuilders.rangeQuery("time").from(startTime).to(endTime))
            .withAggregations(AggregationBuilders.sum("discount").field("discount"))
            .withAggregations(AggregationBuilders.sum("price").field("price"))
            .withPageable(pageable)
            .build()

        val searchHits: SearchHits<Product> = operations.search(query, Product::class.java)

        return searchHits.aggregations 

    }

I return the result of the following code:

    val stats = repository.getTotalStats(before, currentTime, pageable)?.aggregations()

the result is :

{
    "asMap": {
        "discount": {
            "name": "discount",
            "metadata": null,
            "value": 8000.0,
            "valueAsString": "8000.0",
            "type": "sum",
            "fragment": true
        },
        "price": {
            "name": "price",
            "metadata": null,
            "value": 9000.0,
            "valueAsString": "9000.0",
            "type": "sum",
            "fragment": true
        }
    },
    "fragment": true
}

How can I convert above output to an intended output model like following? as I tested contents of aggregations() are inaccessible and the type is Any :

{
    "priceSum":9000.0,
    "discountSum":8000
 }

CodePudding user response:

There is no data model in the Elasticsearch RestHighLevelClient classes for aggregations, and there is no on in Spring Data Elasticsearch. Therefore the original Aggregations object is returned to the caller (contained in that AggregationContainer, because that will change with new new client implementation, and then the container will hold a different object).

You have to parse this by yourself, I had something in the answer of another question (https://stackoverflow.com/a/63105356/4393565). The interesting thing for you is the last codeblock where the aggregations are passed. You basically have to iterate over the elements, cast them to the appropriate type and evaluate them.

  • Related