# 脚本相关改变

原文链接 : [https://www.elastic.co/guide/en/elasticsearch/reference/5.0/breaking_50_scripting.html](https://www.elastic.co/guide/en/elasticsearch/reference/5.0/breaking_50_scripting.html)

译文链接 : [http://www.apache.wiki/pages/viewpage.action?pageId=4260829](http://www.apache.wiki/pages/viewpage.action?pageId=4260829)

贡献者 : [片刻](/display/~jiangzhonglian)

## 切换默认语言从Groovy到Painless

Elasticsearch的默认脚本语言现在是Painless。 Painless是一种定制语言，语法类似于Groovy，旨在快速和安全。 许多Groovy脚本将与Painless脚本相同，以帮助使语言之间的过渡尽可能简单。

Painless的文档可以在[无脚本语言](https://www.elastic.co/guide/en/elasticsearch/reference/5.0/modules-scripting-painless.html)中找到

Groovy和Painless之间的一个常见区别是使用参数 - Painless中的所有参数都必须以params为前缀。 现在。 以下示例显示了区别：

```
{
  "script_score": {
    "script": {
      "lang": "groovy",
      "inline": "Math.log(_score * 2) + my_modifier",
      "params": {
        "my_modifier": 8
      }
    }
  }
}
```

Painless（my_modifer的前缀为params）：

```
{
  "script_score": {
    "script": {
      "lang": "painless",
      "inline": "Math.log(_score * 2) + params.my_modifier",
      "params": {
        "my_modifier": 8
      }
    }
  }
}
```

script.default_lang设置已删除。 不再可能设置默认脚本语言。 如果使用不同于无痛的语言，那么应该在脚本本身上明确指定。

对于没有定义明确语言的脚本，它们是已存储的渗透查询的一部分，可以使用script.legacy.default_lang设置来控制默认语言。

## 删除1.x脚本和模板语法

定义内联脚本/模板和引用文件或索引基础脚本/模板的已弃用的1.x语法已删除。

不能再使用脚本和params字符串参数，而必须使用脚本对象语法。 这适用于更新api，脚本排序，script_score函数，脚本查询，scripted_metric聚合和script_heuristic聚集。

因此，不再允许使用内联脚本：

```
{
  "script_score": {
    "lang": "groovy",
    "script": "Math.log(_score * 2) + my_modifier",
    "params": {
      "my_modifier": 8
    }
  }
}
```

并且必须使用此语法：

```
{
  "script_score": {
    "script": {
      "lang": "groovy",
      "inline": "Math.log(_score * 2) + my_modifier",
      "params": {
        "my_modifier": 8
      }
    }
  }
}
```

脚本或script_file参数不能再用于引用基于文件的脚本和模板，而必须使用文件。

引用基于文件的脚本的此用法不再有效：

```
{
  "script_score": {
    "script": "calculate-score",
    "params": {
      "my_modifier": 8
    }
  }
}
```

此用法有效：

```
{
  "script_score": {
    "script": {
      "lang": "groovy",
      "file": "calculate-score",
      "params": {
        "my_modifier": 8
      }
    }
  }
}
```

script_id参数不能再使用，请参考基于索引的脚本和模板，而必须使用id。

引用索引脚本的此用法不再有效：

```
{
  "script_score": {
    "script_id": "indexedCalculateScore",
    "params": {
      "my_modifier": 8
    }
  }
}
```

此用法有效：

```
{
  "script_score": {
    "script": {
      "id": "indexedCalculateScore",
      "lang" : "groovy",
      "params": {
        "my_modifier": 8
      }
    }
  }
}
```

## 模板查询

模板查询中的查询字段不能再使用。 此1.x语法不能再使用：

```
{
    "query": {
        "template": {
            "query": {"match_{{template}}": {}},
            "params" : {
                "template" : "all"
            }
        }
    }
}
```

而应使用以下语法：

```
{
    "query": {
        "template": {
            "inline": {"match_{{template}}": {}},
            "params" : {
                "template" : "all"
            }
        }
    }
}
```

## 搜索模板

搜索模板API中的顶级模板字段已替换为一致的模板/脚本对象语法。 此1.x语法不能再使用：

```
{
    "template" : {
        "query": { "match" : { "{{my_field}}" : "{{my_value}}" } },
        "size" : "{{my_size}}"
    },
    "params" : {
        "my_field" : "foo",
        "my_value" : "bar",
        "my_size" : 5
    }
}
```

而应使用以下语法：

```
{
    "inline" : {
        "query": { "match" : { "{{my_field}}" : "{{my_value}}" } },
        "size" : "{{my_size}}"
    },
    "params" : {
        "my_field" : "foo",
        "my_value" : "bar",
        "my_size" : 5
    }
}
```

## 索引的脚本和模板

索引脚本和模板已由[存储脚本](https://www.elastic.co/guide/en/elasticsearch/reference/5.0/modules-scripting-using.html#modules-scripting-stored-scripts)替换，这些脚本将脚本和模板存储在集群状态中，而不是专用的.scripts索引。

对于存储的脚本的大小，存在65535个字节的软限制。如果脚本超过该大小，则可以将script.max_size_in_bytes设置添加到elasticsearch.yml以将软限制更改为更高的值。如果脚本真的很大，应考虑其他选项，如本地脚本。

.scripts索引中以前建立索引的脚本将不再使用，因为Elasticsearch现在将尝试从群集状态获取脚本。升级到5.x后，.scripts索引将保持存在，因此脚本可以使用它来将存储的脚本从.scripts索引迁移到群集状态。脚本和模板的当前格式尚未更改，仅删除1.x格式。

### Python迁移脚本

可以使用以下Python脚本将索引脚本作为存储脚本导入到集群状态：

```
from elasticsearch import Elasticsearch,helpers

es = Elasticsearch([
        {'host': 'localhost'}
])

for doc in helpers.scan(es, index=".scripts", preserve_order=True):
        es.put_script(lang=doc['_type'], id=doc['_id'], body=doc['_source'])
```

此脚本使用官方Elasticsearch Python客户端，因此您需要确保您已在您的环境中安装了客户端。 有关这方面的更多信息，请参阅elasticsearch-py。

### Perl迁移脚本

以下Perl脚本可用于将索引脚本作为存储脚本导入到集群状态：

```
use Search::Elasticsearch;

my $es     = Search::Elasticsearch->new( nodes => 'localhost:9200');
my $scroll = $es->scroll_helper( index => '.scripts', sort => '_doc');

while (my $doc = $scroll->next) {
  $e->put_script(
    lang => $doc->{_type},
    id   => $doc->{_id},
    body => $doc->{_source}
  );
}
```

此脚本使用官方Elasticsearch Perl客户端，因此您需要确保您已在您的环境中安装了客户端。有关这方面的更多信息，请参阅Search :: Elasticsearch。

### 验证脚本迁移

在您通过提供的脚本或其他脚本移动脚本后，您可以验证与以下请求如果迁移成功发生：

```
GET _cluster/state?filter_path=metadata.stored_scripts
```

响应应包括.scripts索引中的所有脚本。在验证所有脚本都已移动后，可以选择作为最后一步，您可以删除.scripts索引，因为Elasticsearch不再使用它。

## 索引脚本Java API

与索引脚本交互相关的所有方法都已删除。已在ClusterAdminClient类下添加了用于与存储的脚本进行交互的Java API方法。以前存在于索引脚本API方法上的糖方法不存在于存储脚本的方法上。提供脚本的唯一方法是使用BytesReference实现，如果需要提供字符串，则应该使用BytesArray类。

## 脚本引擎现在只注册一种语言

在5.0.0之前，脚本引擎可以注册多种语言。 Javascript脚本引擎特别注册了“lang”：“js”和“lang”：“javascript”。脚本引擎现在只能注册单一语言。对于lang-javascript插件的现有用户，所有对“lang”：“js”的引用应更改为“lang”：“javascript”。

## 脚本引擎现在只注册一个扩展

在5.0.0脚本引擎之前可以注册多个扩展。唯一的引擎是Javascript引擎，它注册了“js”和“javascript”。它现在只注册磁盘脚本的“js”文件扩展名。

## .javascript文件不再受支持（使用.js）

Javascript引擎以前注册过“js”和“javascript”。它现在只注册磁盘脚本的“js”文件扩展名。

## 从update rest apiedit中删除脚本查询字符串参数

已从更新api中删除脚本script_id和scripting_upsert查询字符串参数。

## Java传输客户端

TemplateQueryBuilder已移至lang-mustache模块。因此，当使用来自Java本机客户端的TemplateQueryBuilder时，lang-mustache模块应该在类路径上。此外，传输客户端应该将lang-mustache模块作为插件加载：

```
TransportClient transportClient = TransportClient.builder()
        .settings(Settings.builder().put("node.name", "node"))
        .addPlugin(MustachePlugin.class)
        .build();
transportClient.addTransportAddress(
        new InetSocketTransportAddress(new InetSocketAddress(InetAddresses.forString("127.0.0.1"), 9300))
);
```

此外，创建TemplateQueryBuilder实例的QueryBuilders类中的帮助方法已被删除，而应使用TemplateQueryBuilder上的构造方法。

## 模板查询

模板查询已被弃用，支持搜索模板api。模板查询计划在下一个主版本中删除。

## GeoPoint脚本

以下助手方法已从GeoPoint脚本中删除：

*   factorDistance
*   factorDistanceWithDefault
*   factorDistance02
*   factorDistance13
*   arcDistanceInKm
*   arcDistanceInKmWithDefault
*   arcDistanceInMiles
*   arcDistanceInMilesWithDefault
*   distanceWithDefault
*   distanceInKm
*   distanceInKmWithDefault
*   distanceInMiles
*   distanceInMilesWithDefault
*   geohashDistanceInKm
*   geohashDistanceInMiles

而是使用arcDistance，arcDistanceWithDefault，planeDistance，planeDistanceWithDefault，geohashDistance，geohashDistanceWithDefault，并使用适当的常数从默认单位（米）转换为所需单位（例如乘以0.001来转换为Km）。