值长度超过 20 的 elasticsearch 查询文本字段

elasticsearch query text field with length of value more than 20

我想使用以下方法查询值(文本)长度超过 20 的名称字段,但不起作用:

GET /groups/_search
{
    "query": {
        "bool" : {
            "must" : {
                "script" : {
                    "script" : "_source.name.values.length() > 20"
                }
            }
        }
    }
}

错误消息是:

{
  "error": {
    "root_cause": [
      {
        "type": "script_exception",
        "reason": "compile error",
        "script_stack": [
          "_source.name.values.lengt ...",
          "^---- HERE"
        ],
        "script": "_source.name.values.length() > 5",
        "lang": "painless"
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "groups",
        "node": "exBbDVGeToSDRzLLmOh8-g",
        "reason": {
          "type": "query_shard_exception",
          "reason": "failed to create query: {\n  \"bool\" : {\n    \"must\" : [\n      {\n        \"script\" : {\n          \"script\" : {\n            \"inline\" : \"_source.name.values.length() > 5\",\n            \"lang\" : \"painless\"\n          },\n          \"boost\" : 1.0\n        }\n      }\n    ],\n    \"disable_coord\" : false,\n    \"adjust_pure_negative\" : true,\n    \"boost\" : 1.0\n  }\n}",
          "index_uuid": "_VH1OfpdRhmd_UPV7uTNMg",
          "index": "groups",
          "caused_by": {
            "type": "script_exception",
            "reason": "compile error",
            "script_stack": [
              "_source.name.values.lengt ...",
              "^---- HERE"
            ],
            "script": "_source.name.values.length() > ",
            "lang": "painless",
            "caused_by": {
              "type": "illegal_argument_exception",
              "reason": "Variable [_source] is not defined."
            }
          }
        }
      }
    ]
  },
  "status": 400
}

不知道我该如何解决...

仅供参考:es的版本是5.4.0

我不知道以下相关问题: Painless script_fields 无法访问 _source 变量 #20068 https://github.com/elastic/elasticsearch/issues/20068

您可以使用:

params._source.name.length() > 20

如果这是一个罕见的查询,这样做可能没问题。否则,您应该为名称长度添加一个字段,并使用 range 查询。

处理这个问题的最好和最优化的方法是同时使用 name 字段的长度索引另一个字段,我们称它为 nameLength。这样您就可以转移在索引时计算名称字段长度的负担,而不必在查询时(重复)计算。

因此在索引时,如果您有一个 name 字段,例如 {"name": "A big brown fox"},那么您将创建一个具有名称字段长度的新字段,例如 {"name": "A big brown fox", "nameLength": 15}.

在查询时,您将能够在 nameLength 字段上使用简单快速的 range 查询:

GET /groups/_search
{
    "query": {
        "bool" : {
            "must" : {
                "range" : {
                    "nameLength": {
                       "gt": 20
                    }
                }
            }
        }
    }
}