Browse Source

Make Painless the default scripting language.

Closes #20017
Jack Conradson 9 years ago
parent
commit
131e370a16

+ 2 - 2
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<ScriptService.ScriptType, Setting<Boolean>> 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;

+ 2 - 2
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() {

+ 1 - 1
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"
             }
           }
         }

+ 1 - 1
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"
                     }
                 }
             }

+ 2 - 2
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"
                     }
                 }
             }

+ 47 - 0
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 <<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

+ 8 - 6
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());
     }

+ 10 - 8
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");
     }

+ 3 - 0
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
 

+ 1 - 0
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: