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

Avi*_*Avi 5 scripting nested elasticsearch elasticsearch-painless

对此有很多疑问和答案,但仍然没有得到满意的答案。弹性搜索版本:6.5

索引映射

"_doc": {
    "properties": {
      "ssid": {
        "type": "long"
      },
      "nested_field": {
        "type": "nested"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

搜索查询:

{
  "query": {
    "bool": {
      "filter": {
        "script": {
          "script": "params._source.nested_field.size() > 1"
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

还尝试了下面的查询但没有运气

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

错误

{
  "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
}
Run Code Online (Sandbox Code Playgroud)

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

Joe*_*ook 4

尽管这会很慢并且不符合在搜索查询中访问的指导,但该查询在 v6.4 之前就可以工作。_source

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

话虽如此,您可以“劫持”一个function_score查询,其 Painless 上下文仍然可以访问_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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用 apipeline来计算字段大小,然后将其保存在文档的顶层。

或者,您可以按照我的相关答案copy_to中的概述使用。