如果您使用Elasticsearch 5.5
和动态字段Map并使用双精度值。当我签入Map时,这些值将获得浮点类型。当您使用聚合时,桶中的键将失去精度。值0.62
将类似于0.6200000047683716
。
代码片段
"aggregations": {
"float_numbers": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 0.6200000047683716,
"doc_count": 1
}
]
}
}
这里描述了相同的问题。link
我发布这个问题是因为我找到了一个合适的解决方案,我还没有看到,但它帮助了我很大。
解决方法是使浮点数为双精度型。这可以通过动态模板来实现。
动态模板
dynamic field mapping
示例解决方案:
在索引中添加dynamic_templates
,还没有项目。
PUT term-test
{
"mappings": {
"demo_typ": {
"dynamic_templates": [
{
"all_to_double": {
"match_mapping_type": "double",
"mapping": {
"type": "double"
}
}
}
]
}
}
}
添加数据
POST term-test/demo_typ
{
"numeric_field": 0.62,
"long_filed": 44
}
检查Map
GET term-test/_mapping
执行聚合
GET term-test/_search
{
"query": {
"match_all": {}
},
"aggs": {
"float_numbers": {
"terms": {
"field": "numeric_field"
}
}
}
}
- 在Java API中,您可以执行以下操作**
1:首先创建索引
elasticClient.admin()
.indices()
.prepareCreate(indexName)
.execute()
.actionGet();
2:更新Map
JSON语言
{
"dynamic_templates": [
{
"all_to_double": {
"match_mapping_type": "double",
"mapping": {
"type": "double"
}
}
}
]
}
我从link获得了代码
public XContentBuilder getXContentBuilderFromJson(final String json) {
try {
Map<String, Object> map = new ObjectMapper().readValue(json, new TypeReference<Map<String, Object>>() {});
return XContentFactory.jsonBuilder().map(map);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
更新Map
elasticClient.admin().indices()
.preparePutMapping(indexName)
.setType(yourType)
.setSource(getXContentBuilderFromJson(json))
.execute()
.actionGet();
3:插入数据
1条答案
按热度按时间i1icjdpr1#
数字会失去精度。这是因为浮点数的工作方式:9.62不能表示为a * 2 ^ b,因此无论是双精度型还是浮点型都不能准确地表示它。
由于浮点型和双精度型不能准确地表示值,因此对它们运行术语聚合通常不是一个好主意。
作为一种解决方法,您可以在聚合之后执行
Math.round