如何将Elasticsearch Spring Data的AggregationsContainer内容映射到自定义模型?
我之前也碰到过Spring Data Elasticsearch聚合结果映射的问题,确实有点绕,不过掌握了类型转换的技巧就好办了。咱们一步步来解决你的问题:
第一步:定义目标模型
先把你想要的自定义模型写好,这样后续可以直接把聚合结果往里塞:
data class ProductStats( val priceSum: Double, val discountSum: Double )
第二步:修改仓库方法,直接返回自定义模型
你之前的方法返回AggregationsContainer会让调用方处理起来很麻烦,不如直接在仓库层就把聚合结果转换成目标模型。另外注意:不要多次调用withAggregations,这个方法会覆盖之前的聚合配置,应该用addAggregation来添加多个聚合:
override fun getStats(startTime: Long, endTime: Long, pageable: Pageable): ProductStats? { val query = NativeSearchQueryBuilder() .withQuery(QueryBuilders.rangeQuery("time").from(startTime).to(endTime)) // 用addAggregation添加多个聚合,避免覆盖 .addAggregation(AggregationBuilders.sum("discount").field("discount")) .addAggregation(AggregationBuilders.sum("price").field("price")) .withPageable(pageable) .build() val searchHits = operations.search(query, Product::class.java) val aggregations = searchHits.aggregations ?: return null // 强转成SumAggregation,直接获取聚合值 val discountSum = aggregations.get<SumAggregation>("discount")?.value ?: 0.0 val priceSum = aggregations.get<SumAggregation>("price")?.value ?: 0.0 return ProductStats(priceSum, discountSum) }
第三步:调用方法直接使用模型
现在调用的时候就非常清爽了,直接访问模型的属性即可:
val stats = repository.getStats(before, currentTime, pageable) println("总价格:${stats?.priceSum},总折扣:${stats?.discountSum}")
如果非要处理AggregationsContainer的情况
要是你因为某些原因必须保留原方法的返回值,也可以这样做:
val aggregationsContainer = repository.getStats(before, currentTime, pageable) // 将aggregations()返回的Any强转为Elasticsearch的Aggregations对象 val aggregations = aggregationsContainer?.aggregations() as? Aggregations aggregations?.let { val discountSum = it.get<SumAggregation>("discount")?.value ?: 0.0 val priceSum = it.get<SumAggregation>("price")?.value ?: 0.0 val productStats = ProductStats(priceSum, discountSum) // 这里使用转换后的模型 }
关键原理说明
Spring Data Elasticsearch的AggregationsContainer是一个通用容器,里面的aggregations()返回的Any其实是Elasticsearch原生的Aggregations对象。我们通过get<T>(aggName)方法指定具体的聚合类型(比如SumAggregation对应sum聚合),就能直接访问聚合的value属性,避免了操作Map的麻烦。
内容的提问来源于stack exchange,提问作者FargolK
相关产品推荐
相关产品推荐

