【问题标题】:How to store money in elasticsearch如何在elasticsearch中存钱
【发布时间】:2015-08-26 08:09:22
【问题描述】:

我创建了一个弹性搜索索引,我当前的映射将项目的美元金额存储为一个字符串。事实证明这很困难,因为我无法正确搜索/过滤此值。

GET catalog/product/_search
{
  "filter": {
    "range": {
      "price": {
        "from": 230.0,
        "to": 300.0
      }
    }
  }
}

其中价格被映射为字符串。我使用了一个字符串,因为从一个 python 十进制值开始,我遇到了这个值突然获得像 17.989999999999999999998789 这样的值的问题。这只有时会发生,但我不想涉及从 python 十进制到 java double/float 的问题(所以我只是 str() 的东西)。

对更好的方法有任何想法吗?我应该咬紧牙关将价格映射到双倍还是浮动?

【问题讨论】:

  • 问题是 ElasticSearch 没有 decimal 类型,因此它可能正在转换为 float。乘以 100 并存储为美分,然后转换应用程序端?再见精度问题。
  • 这是个好主意。如果您回答,我可以将其标记为这样。唯一的问题是返回大量数据,循环遍历所有这些项目可能是昂贵(缓慢)的应用程序端。我可以使用 ES 脚本,但我认为这也很慢。
  • 你可能还想看看这个问题的第一个答案stackoverflow.com/questions/1458633/…

标签: python elasticsearch


【解决方案1】:

在较新的版本(检查为 5.0)中,最好的选择可能是将scaled_floatscaling_factor = 100 一起使用,就像他们的示例中一样:

PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "number_of_bytes": {
          "type": "integer"
        },
        "time_in_seconds": {
          "type": "float"
        },
        "price": {
          "type": "scaled_float",
          "scaling_factor": 100
        }
      }
    }
  }
}

你可以在这里找到他们的doc

【讨论】:

  • 为 scaled_float 数据类型添加数据的语法是什么。我收到错误 ` { "error": { "root_cause": [ { "type": "mapper_parsing_exception", "reason": "failed to parse" } ], "type": "mapper_parsing_exception", "reason": “解析失败”,“caused_by”:{“type”:“illegal_argument_exception”,“reason”:“字段 [val] 缺少必需的参数 [scaling_factor]”}},“status”:400 } `
  • 遇到了同样的问题:映射与上面示例中的特定类型(如“my_type”)相关。使用 High-Level-Rest-Client 时,它总是在新的默认“_doc”类型下创建映射。使用其他类型插入数据时会出现错误。将插入更改为 _doc 类型后,错误消失了
  • 存在与 scaled_float 类型相关的精度问题,因此不应将其用于财务字段/属性github.com/elastic/elasticsearch/issues/32570
  • @dgt 看起来精度问题已在 2019 年 1 月左右在 7.0 中从您链接到的那个问题中得到修复
【解决方案2】:

出现这种情况是因为 ElasticSearch 没有内置的小数或货币类型,因此您的值很可能被转换为 float 并遇到浮点精度问题。

您应该能够通过简单地将值存储为long(例如美分而不是美元的数量)并在您的decimal 应用程序端转换来解决这个问题。

由于您只会对已枚举的值进行此转换,因此对性能的影响应该可以忽略不计。

【讨论】:

    猜你喜欢
    • 2011-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多