diff --git a/core/src/main/java/org/elasticsearch/script/ScriptSettings.java b/core/src/main/java/org/elasticsearch/script/ScriptSettings.java index e315f8d816c..3301e2e08aa 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptSettings.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptSettings.java @@ -32,7 +32,7 @@ import java.util.function.Function; public class ScriptSettings { - public static final String DEFAULT_LANG = "groovy"; + public static final String DEFAULT_LANG = "painless"; private static final Map> SCRIPT_TYPE_SETTING_MAP; @@ -59,7 +59,7 @@ public class ScriptSettings { this.scriptLanguageSettings = Collections.unmodifiableList(scriptLanguageSettings); this.defaultScriptLanguageSetting = new Setting<>("script.default_lang", DEFAULT_LANG, setting -> { - if (!"groovy".equals(setting) && !scriptEngineRegistry.getRegisteredLanguages().containsKey(setting)) { + if (!DEFAULT_LANG.equals(setting) && !scriptEngineRegistry.getRegisteredLanguages().containsKey(setting)) { throw new IllegalArgumentException("unregistered default language [" + setting + "]"); } return setting; diff --git a/core/src/test/java/org/elasticsearch/script/ScriptSettingsTests.java b/core/src/test/java/org/elasticsearch/script/ScriptSettingsTests.java index 053ccec652c..8c1654fb902 100644 --- a/core/src/test/java/org/elasticsearch/script/ScriptSettingsTests.java +++ b/core/src/test/java/org/elasticsearch/script/ScriptSettingsTests.java @@ -32,12 +32,12 @@ import static org.hamcrest.Matchers.equalTo; public class ScriptSettingsTests extends ESTestCase { - public void testDefaultLanguageIsGroovy() { + public void testDefaultLanguageIsPainless() { ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(Collections.singletonList(new CustomScriptEngineService())); ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Collections.emptyList()); ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, scriptContextRegistry); - assertThat(scriptSettings.getDefaultScriptLanguageSetting().get(Settings.EMPTY), equalTo("groovy")); + assertThat(scriptSettings.getDefaultScriptLanguageSetting().get(Settings.EMPTY), equalTo("painless")); } public void testCustomDefaultLanguage() { diff --git a/docs/reference/aggregations/pipeline.asciidoc b/docs/reference/aggregations/pipeline.asciidoc index da78e188559..499438256e6 100644 --- a/docs/reference/aggregations/pipeline.asciidoc +++ b/docs/reference/aggregations/pipeline.asciidoc @@ -165,7 +165,7 @@ POST /sales/_search "count": "categories._bucket_count" <1> }, "script": { - "inline": "count != 0" + "inline": "params.count != 0" } } } diff --git a/docs/reference/aggregations/pipeline/bucket-script-aggregation.asciidoc b/docs/reference/aggregations/pipeline/bucket-script-aggregation.asciidoc index 1bfd080090a..6a010650e5c 100644 --- a/docs/reference/aggregations/pipeline/bucket-script-aggregation.asciidoc +++ b/docs/reference/aggregations/pipeline/bucket-script-aggregation.asciidoc @@ -77,7 +77,7 @@ POST /sales/_search "tShirtSales": "t-shirts>sales", "totalSales": "total_sales" }, - "script": "tShirtSales / totalSales * 100" + "script": "params.tShirtSales / params.totalSales * 100" } } } diff --git a/docs/reference/aggregations/pipeline/bucket-selector-aggregation.asciidoc b/docs/reference/aggregations/pipeline/bucket-selector-aggregation.asciidoc index 86a56a77aa2..685c40f4830 100644 --- a/docs/reference/aggregations/pipeline/bucket-selector-aggregation.asciidoc +++ b/docs/reference/aggregations/pipeline/bucket-selector-aggregation.asciidoc @@ -23,7 +23,7 @@ A `bucket_selector` aggregation looks like this in isolation: "my_var1": "the_sum", <1> "my_var2": "the_value_count" }, - "script": "my_var1 > my_var2" + "script": "params.my_var1 > params.my_var2" } } -------------------------------------------------- @@ -66,7 +66,7 @@ POST /sales/_search "buckets_path": { "totalSales": "total_sales" }, - "script": "totalSales > 200" + "script": "params.totalSales > 200" } } } diff --git a/docs/reference/migration/migrate_5_0/scripting.asciidoc b/docs/reference/migration/migrate_5_0/scripting.asciidoc index 52a26c89d1b..4d42ae98b46 100644 --- a/docs/reference/migration/migrate_5_0/scripting.asciidoc +++ b/docs/reference/migration/migrate_5_0/scripting.asciidoc @@ -1,6 +1,53 @@ [[breaking_50_scripting]] === Script related changes +==== Switched Default Language from Groovy to Painless + +The default scripting language for Elasticsearch is now Painless. Painless is a custom-built language with syntax +similar to Groovy designed to be fast as well as secure. Many Groovy scripts will be identitical to Painless scripts +to help make the transition between languages as simple as possible. + +Documentation for Painless can be found at <> + +It is also possible to set the default language back to Groovy using the following setting: `script.default_lang: groovy` + +One common difference to note between Groovy and Painless is the use of parameters -- all parameters in Painless +must be prefixed with `params.` now. The following example shows the difference: + +Groovy: + +[source,js] +----------------------------------- +{ + "script_score": { + "script": { + "lang": "groovy", + "inline": "Math.log(_score * 2) + my_modifier", + "params": { + "my_modifier": 8 + } + } + } +} +----------------------------------- + +Painless (`my_modifer` is prefixed with `params`): + +[source,js] +----------------------------------- +{ + "script_score": { + "script": { + "lang": "painless", + "inline": "Math.log(_score * 2) + params.my_modifier", + "params": { + "my_modifier": 8 + } + } + } +} +----------------------------------- + ==== Removed 1.x script and template syntax The deprecated 1.x syntax of defining inline scripts / templates and referring to file or index base scripts / templates diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyIndexedScriptTests.java b/modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyIndexedScriptTests.java index be307c690f9..b0d5fd3366b 100644 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyIndexedScriptTests.java +++ b/modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyIndexedScriptTests.java @@ -70,12 +70,12 @@ public class GroovyIndexedScriptTests extends ESIntegTestCase { public void testFieldIndexedScript() throws ExecutionException, InterruptedException { client().admin().cluster().preparePutStoredScript() .setId("script1") - .setScriptLang("groovy") + .setScriptLang(GroovyScriptEngineService.NAME) .setSource(new BytesArray("{ \"script\" : \"2\"}")) .get(); client().admin().cluster().preparePutStoredScript() .setId("script2") - .setScriptLang("groovy") + .setScriptLang(GroovyScriptEngineService.NAME) .setSource(new BytesArray("{ \"script\" : \"factor * 2\"}")) .get(); @@ -93,8 +93,9 @@ public class GroovyIndexedScriptTests extends ESIntegTestCase { .prepareSearch() .setSource( new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).size(1) - .scriptField("test1", new Script("script1", ScriptType.STORED, "groovy", null)) - .scriptField("test2", new Script("script2", ScriptType.STORED, "groovy", script2Params))) + .scriptField("test1", new Script("script1", ScriptType.STORED, GroovyScriptEngineService.NAME, null)) + .scriptField("test2", + new Script("script2", ScriptType.STORED, GroovyScriptEngineService.NAME, script2Params))) .setIndices("test").setTypes("scriptTest").get(); assertHitCount(searchResponse, 5); assertTrue(searchResponse.getHits().hits().length == 1); @@ -120,7 +121,8 @@ public class GroovyIndexedScriptTests extends ESIntegTestCase { .prepareSearch() .setSource( new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).scriptField("test_field", - new Script("script1", ScriptType.STORED, "groovy", null))).setIndices("test_index") + new Script("script1", ScriptType.STORED, GroovyScriptEngineService.NAME, null))) + .setIndices("test_index") .setTypes("test_type").get(); assertHitCount(searchResponse, 1); SearchHit sh = searchResponse.getHits().getAt(0); @@ -157,7 +159,7 @@ public class GroovyIndexedScriptTests extends ESIntegTestCase { .prepareSearch("test") .setSource( new SearchSourceBuilder().aggregation(AggregationBuilders.terms("test").script( - new Script("script1", ScriptType.STORED, null, null)))).get(); + new Script("script1", ScriptType.STORED, GroovyScriptEngineService.NAME, null)))).get(); assertHitCount(searchResponse, 1); assertThat(searchResponse.getAggregations().get("test"), notNullValue()); } diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyScriptTests.java b/modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyScriptTests.java index f2eee2bb408..88d9b7be1de 100644 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyScriptTests.java +++ b/modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyScriptTests.java @@ -68,7 +68,7 @@ public class GroovyScriptTests extends ESIntegTestCase { } public void assertScript(String scriptString) { - Script script = new Script(scriptString, ScriptType.INLINE, "groovy", null); + Script script = new Script(scriptString, ScriptType.INLINE, GroovyScriptEngineService.NAME, null); SearchResponse resp = client().prepareSearch("test") .setSource(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).sort(SortBuilders. scriptSort(script, ScriptSortType.NUMBER))) @@ -99,7 +99,8 @@ public class GroovyScriptTests extends ESIntegTestCase { try { client().prepareSearch("test") - .setQuery(constantScoreQuery(scriptQuery(new Script("null.foo", ScriptType.INLINE, "groovy", null)))).get(); + .setQuery(constantScoreQuery(scriptQuery( + new Script("null.foo", ScriptType.INLINE, GroovyScriptEngineService.NAME, null)))).get(); fail("should have thrown an exception"); } catch (SearchPhaseExecutionException e) { assertThat(e.toString() + "should not contained NotSerializableTransportException", @@ -118,8 +119,9 @@ public class GroovyScriptTests extends ESIntegTestCase { refresh(); // doc[] access - SearchResponse resp = client().prepareSearch("test").setQuery(functionScoreQuery(scriptFunction(new Script("doc['bar'].value", ScriptType.INLINE, "groovy", null))) - .boostMode(CombineFunction.REPLACE)).get(); + SearchResponse resp = client().prepareSearch("test").setQuery(functionScoreQuery(scriptFunction( + new Script("doc['bar'].value", ScriptType.INLINE, GroovyScriptEngineService.NAME, null))) + .boostMode(CombineFunction.REPLACE)).get(); assertNoFailures(resp); assertOrderedSearchHits(resp, "3", "2", "1"); @@ -133,7 +135,7 @@ public class GroovyScriptTests extends ESIntegTestCase { // _score can be accessed SearchResponse resp = client().prepareSearch("test").setQuery(functionScoreQuery(matchQuery("foo", "dog"), - scriptFunction(new Script("_score", ScriptType.INLINE, "groovy", null))) + scriptFunction(new Script("_score", ScriptType.INLINE, GroovyScriptEngineService.NAME, null))) .boostMode(CombineFunction.REPLACE)).get(); assertNoFailures(resp); assertSearchHits(resp, "3", "1"); @@ -144,9 +146,9 @@ public class GroovyScriptTests extends ESIntegTestCase { resp = client() .prepareSearch("test") .setQuery( - functionScoreQuery(matchQuery("foo", "dog"), - scriptFunction(new Script("_score > 0.0 ? _score : 0", ScriptType.INLINE, "groovy", null))).boostMode( - CombineFunction.REPLACE)).get(); + functionScoreQuery(matchQuery("foo", "dog"), scriptFunction( + new Script("_score > 0.0 ? _score : 0", ScriptType.INLINE, GroovyScriptEngineService.NAME, null))) + .boostMode(CombineFunction.REPLACE)).get(); assertNoFailures(resp); assertSearchHits(resp, "3", "1"); } diff --git a/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/25_script_upsert.yaml b/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/25_script_upsert.yaml index 3ab70d084fa..6ba4d39e71b 100644 --- a/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/25_script_upsert.yaml +++ b/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/25_script_upsert.yaml @@ -13,6 +13,7 @@ script: inline: "ctx._source.foo = bar" params: { bar: 'xxx' } + lang: "groovy" upsert: { foo: baz } - do: @@ -33,6 +34,7 @@ script: inline: "ctx._source.foo = bar" params: { bar: 'xxx' } + lang: "groovy" upsert: { foo: baz } - do: @@ -52,6 +54,7 @@ script: inline: "ctx._source.foo = bar" params: { bar: 'xxx' } + lang: "groovy" upsert: { foo: baz } scripted_upsert: true diff --git a/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/90_missing.yaml b/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/90_missing.yaml index c49565a6304..999d9f610ff 100644 --- a/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/90_missing.yaml +++ b/modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/90_missing.yaml @@ -34,6 +34,7 @@ script: inline: "ctx._source.foo = bar" params: { bar: 'xxx' } + lang: "groovy" - do: update: