Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Painless the Default Language #20017

Closed
wants to merge 12 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

public class ScriptSettings {

public static final String DEFAULT_LANG = "groovy";
public static final String DEFAULT_LANG = "painless";

private static final Map<ScriptService.ScriptType, Setting<Boolean>> SCRIPT_TYPE_SETTING_MAP;

Expand All @@ -59,7 +59,7 @@ public ScriptSettings(ScriptEngineRegistry scriptEngineRegistry, ScriptContextRe
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@

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() {
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/aggregations/pipeline.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ POST /sales/_search
"count": "categories._bucket_count" <1>
},
"script": {
"inline": "count != 0"
"inline": "params.count != 0"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ POST /sales/_search
"tShirtSales": "t-shirts>sales",
"totalSales": "total_sales"
},
"script": "tShirtSales / totalSales * 100"
"script": "params.tShirtSales / params.totalSales * 100"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
--------------------------------------------------
Expand Down Expand Up @@ -66,7 +66,7 @@ POST /sales/_search
"buckets_path": {
"totalSales": "total_sales"
},
"script": "totalSales > 200"
"script": "params.totalSales > 200"
}
}
}
Expand Down
47 changes: 47 additions & 0 deletions docs/reference/migration/migrate_5_0/scripting.asciidoc
Original file line number Diff line number Diff line change
@@ -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 <<modules-scripting-painless,Painless Scripting Language>>

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ protected Settings nodeSettings(int nodeOrdinal) {
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();

Expand All @@ -93,8 +93,9 @@ public void testFieldIndexedScript() throws ExecutionException, InterruptedExce
.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);
Expand All @@ -120,7 +121,8 @@ public void testUpdateScripts() {
.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);
Expand Down Expand Up @@ -157,7 +159,7 @@ public void testDisabledAggsDynamicScripts() {
.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());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public void testGroovyBigDecimalTransformation() {
}

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)))
Expand Down Expand Up @@ -99,7 +99,8 @@ public void testGroovyExceptionSerialization() throws Exception {

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",
Expand All @@ -118,8 +119,9 @@ public void testGroovyScriptAccess() {
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");
Expand All @@ -133,7 +135,7 @@ public void testScoreAccess() {

// _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");
Expand All @@ -144,9 +146,9 @@ public void testScoreAccess() {
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");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
script:
inline: "ctx._source.foo = bar"
params: { bar: 'xxx' }
lang: "groovy"
upsert: { foo: baz }

- do:
Expand All @@ -33,6 +34,7 @@
script:
inline: "ctx._source.foo = bar"
params: { bar: 'xxx' }
lang: "groovy"
upsert: { foo: baz }

- do:
Expand All @@ -52,6 +54,7 @@
script:
inline: "ctx._source.foo = bar"
params: { bar: 'xxx' }
lang: "groovy"
upsert: { foo: baz }
scripted_upsert: true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
script:
inline: "ctx._source.foo = bar"
params: { bar: 'xxx' }
lang: "groovy"

- do:
update:
Expand Down