Elasticsearch搜索查询:为什么params._source.nested_field.size()在脚本中不起作用?

时间:2019-01-03 12:26:48

标签: elasticsearch scripting nested elasticsearch-painless

对此有很多疑问和答案,但仍未获得满意的答案。 Elasticsearch版本:6.5

索引映射

"_doc": {
    "properties": {
      "ssid": {
        "type": "long"
      },
      "nested_field": {
        "type": "nested"
      }
    }
  }
}

搜索查询:

{
  "query": {
    "bool": {
      "filter": {
        "script": {
          "script": "params._source.nested_field.size() > 1"
        }
      }
    }
  }
}

也在下面的查询中尝试过但没有运气

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "nested_field",
            "query": {
              "bool": {
                "filter": {
                  "script": {
                    "script": "params._source.nested_field.size() > 1"
                  }
                }
              }
            }
          }
        }
      ]
    }
  }
}

错误

{
  "error": {
    "root_cause": [
      {
        "type": "script_exception",
        "reason": "runtime error",
        "script_stack": [
          "params._source.nested_field.size() > 1",
          "              ^---- HERE"
        ],
        "script": "params._source.nested_field.size() > 1",
        "lang": "painless"
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "testing_index",
        "node": "XXXXXXXXXXXXXXXXXXXXXXX",
        "reason": {
          "type": "script_exception",
          "reason": "runtime error",
          "script_stack": [
            "params._source.nested_field.size() > 1",
            "              ^---- HERE"
          ],
          "script": "params._source.nested_field.size() > 1",
          "lang": "painless",
          "caused_by": {
            "type": "null_pointer_exception",
            "reason": null
          }
        }
      }
    ]
  },
  "status": 500
}

params._source.nested_field在scripted_field中使用时返回嵌套数组,但在验证查询中不起作用。有关使用无痛脚本的嵌套查询的文档并不完整。

1 个答案:

答案 0 :(得分:1)

尽管这会很慢并且against the guidance 在搜索查询中访问def is_even(x): return x % 2 == 0 def is_odd(x): return not is_even(x) is_odd(3) # True ,但该查询在 v6.4 之前可以正常工作。 >

v6.4 之后,由于 refactoring 的无意副作用,无法在脚本查询上下文中访问 _source

话虽如此,您可以“劫持”一个 _source 查询,其无痛上下文仍然可以访问 function_score

_source

您可以使用 { "query": { "function_score": { "query": { "match_all": {} }, "functions": [ { "script_score": { "script": { "source": "params._source.containsKey('nested_field') && params._source['nested_field'] != null && params._source.nested_field.size() > 1 ? 1 : 0" } } } ], "min_score": 1 } } } 来计算字段大小,然后将其保存在文档的顶层。

或者,您可以使用 my related answer 中概述的 pipeline