首页 > 解决方案 > 是否可以在 Elasticsearch 中按范围排序?

问题描述

当我执行以下查询时:

{
  "query": {
    "bool": {
      "filter": [
        {
          "match": {
            "my_value": "hi"
          }
        },
        {
          "range": {
            "my_range": {
              "gt": 0,
              "lte": 200
            }
          }
        }
      ]
    }
  },
  "sort": {
    "my_range": {
      "order": "asc",
      "mode": "min"
    }
  }
}

我得到错误:

"caused_by": {
  "type": "illegal_argument_exception",
  "reason": "Fielddata is not supported on field [my_range] of type [long_range]"
}

如何使range数据类型可排序?这可能吗?

Elasticsearch 版本:5.4,但我想知道这是否适用于任何版本。

更多上下文

并非别名/索引中的所有文档都具有范围字段。但是,查询过滤器只包含具有该字段的文档。

标签: sortingelasticsearchrange

解决方案


使用范围数据类型的字段进行排序并不简单。您仍然可以在某种程度上使用基于脚本的排序来获得预期的结果。

例如,为了简单起见,我假设您的所有文档的脚本,针对my_range字段索引的数据只有数据,gt并且lte您想根据两者的最小值进行排序,然后您可以添加以下内容进行排序:

{
  "query": {
    "bool": {
      "filter": [
        {
          "match": {
            "my_value": "hi"
          }
        },
        {
          "range": {
            "my_range": {
              "gt": 0,
              "lte": 200
            }
          }
        }
      ]
    }
  },
  "sort": {
    "_script": {
      "type": "number",
      "script": {
        "lang": "painless",
        "inline": "Math.min(params['_source']['my_range']['gt'], params['_source']['my_range']['lte'])"            
      },
      "order": "asc"
    }
  }
}

您可以根据您对涉及所有lt, gt, lte,组合的复杂数据的需要修改脚本gte

更新(其他不同用例的脚本):

1.按差异排序
"Math.abs(params['_source']['my_range']['gt'] - params['_source']['my_range']['lte'])"
2. 排序方式gt
"params['_source']['my_range']['gt']"
3. 排序方式lte
"params['_source']['my_range']['lte']"
4.如果查询返回少数没有range字段的文档,则排序
"if(params['_source']['my_range'] != null) { <sorting logic> } else { return 0; }"

替换<sorting logic>为所需的排序逻辑(可以是上面3个之一或查询中的一个)

return 0可以根据return -1排序需要替换为或任何其他数字


推荐阅读