Elasticsearch Java API客户端将聚合键作为字符串返回,而不是数字
我正在使用Elasticsearch Java API Client来执行带聚合的查询。
在Elasticsearch中,我的字段映射是:
"departmentId": {
"type": "integer"
}
我的聚合查询是在该字段上的terms聚合。
预期行为
从Elasticsearch的响应(原始JSON),我期望得到:
"key": 1
(即数值)
实际行为(Java客户端)
使用:
SearchResponse<JsonData> response = esClient.search(request, JsonData.class);
甚至:
SearchResponse<Map> response = esClient.search(request, Map.class);
我得到:
"key": "1"
(即字符串而不是数字)
观察
- 这个问题仅在 聚合 中出现,而不是在
_source中 -
我对Java客户端进行了调试,发现:
-
聚合的解析使用
TypedKeysDeserializer - 桶键(bucket keys)的反序列化使用
JsonpDeserializer.STRING -
内部,它会调用:
parser.getString()+这接收VALUE_NUMBER并将其转换为字符串
问题
- 这是Elasticsearch Java API Client的预期行为吗?
- 有没有办法配置客户端将聚合键返回为数值类型而不是字符串?
- 还是手动转换是唯一推荐的方式?
环境
-
Elasticsearch版本:
7.17.9* Elasticsearch Java Client版本:7.17.9* Java版本:17
解决方案
是的,在Elasticsearch 7.17.9 版本中这是预期的行为,因为Terms聚合会将键转换为字符串,并且它支持字段的多种数据类型,如字符串、数值、布尔值等。你需要迁移到Elasticsearch 8.1.0 或更高版本,才能把键作为整数读取。
如果你确定 departmentId 始终会返回数值,你可以在Java代码中将其从字符串转换为整数。
下面的代码可在 8.1.0 下使用,无需再进行字符串到整数的转换。
Aggregate agg = response.aggregations().get("departmentIdAgg");
if (agg.isLterms()) {
for (LongTermsBucket bucket : agg.lterms().buckets().array()) {
int departmentId = Integer.parseInt(bucket.key());
long docCount = bucket.docCount();
// use departmentId and docCount
}
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。