Elasticsearch排序脚本只能访问字符串形式的关键字字段

ldioqlga  于 5个月前  发布在  ElasticSearch
关注(0)|答案(1)|浏览(77)

这是我的查询,Elasticsearch版本是7.10.0

{
    "query": {
      "bool": {
        "must": [
          {
            "match_all": {}
          }
        ]
      }
    },
    "sort": {
      "_script": {
        "type": "number",
        "script": {
          "lang": "painless",
          "source": "doc['my_field'].value - params.paramVal",
          "params": {
            "paramVal": 1
          }
        },
        "order": "asc"
      }
    },
    "profile": false
  }

字符串
其中my_field是一个关键字字段。但此查询导致错误

"reason": {
    "type": "script_exception",
    "reason": "runtime error",
    "script_stack": [
      "doc['my_field'].value - params.paramVal",
      "                              ^---- HERE"
    ],
    "script": "doc['my_field'].value - params.paramVal",
    "lang": "painless",
    "position": {
      "offset": 33,
      "start": 0,
      "end": 49
    },
    "caused_by": {
      "type": "class_cast_exception",
      "reason": "class_cast_exception: Cannot apply [-] operation to types [java.lang.String] and [java.lang.Integer]."
    }
  }


现在我使用了.parseInt(document'my_field'].value)来解决这个问题。有没有直接使用int字段值的想法?谢谢。

watbbzwu

watbbzwu1#

如果my_field是一个“关键字字段”,我假设它被存储为一个字符串。如果是这种情况,那么doc['my_field'].value返回一个字符串,Painless不允许你从字符串中减去一个整数。你需要解析这个字符串,像这样:

Integer.parseInt(doc['my_field'].value) - params.paramVal

字符串
如果my_field应该包含一个整数值,那么你应该将其存储为integer类型而不是关键字,特别是当你需要在该字段上运行range查询时。

更新:

如果你不想或不能重新索引,并希望仍然保持当前索引,你可以做的另一件事是添加一个integer子字段并更新你的索引。它是这样的:

# First add an integer sub-field to your mapping
PUT index/_mapping
{
   "properties": {
      "my_field": {
         "type": "keyword",
         "fields": {
            "numeric": {
               "type": "integer"
            }
         }
      }
   }
}

# then update your index in-place
POST index/_update_by_query


更新完成后,新的my_field.numeric字段将使用关键字字段中的现有数据填充,您可以在Painless脚本中使用它,如下所示:

doc['my_field.numeric'].value - params.paramVal

相关问题