es的range失效

es的range失效的解决方法

问题描述

当我们es使用keyword类型存储数字时,当我们使用range时我们发现range失效的问题,例如以下的用例:

我们创建一个test1的索引test1:

es的range失效_第1张图片

使用_bulk进行批量导入数据:

es的range失效_第2张图片

进行查询我们发现我们要使用range进行0-5000的范围查询,但发现10000出现了

es的range失效_第3张图片

这是为什么呢?

原因解释:因为es的keyword的字符串比较是按字典序进行的(“100” < “20” 因为 ‘1’ < ‘2’),同理5000>10000是因为5>1

如何解决呢?

正确解决方案

方案1:重新映射字段为数值类型(推荐)

PUT /products/_mapping
{
  "properties": {
    "price": {
      "type": "float"  // 或 "integer"
    }
  }
}

然后使用数值类型的 range 查询。

方案2:使用脚本转换字符串为数值(性能较差)

GET /products/_search
{
  "query": {
    "script": {
      "script": {
        "source": "Double.parseDouble(doc['price'].value) >= params.min && Double.parseDouble(doc['price'].value) <= params.max",
        "params": {
          "min": 100,
          "max": 500
        }
      }
    }
  }
}

方案3:使用标准化格式存储文本价格(次优方案)

如果必须保持文本类型,确保所有价格:

  • 统一小数位数(如都保留2位:100.00)
    化格式存储文本价格(次优方案)

如果必须保持文本类型,确保所有价格:

  • 统一小数位数(如都保留2位:100.00)
  • 统一数字

你可能感兴趣的:(elasticsearch)