diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index 9c6e36a2e1d0d..83a50be4f6f78 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -12,6 +12,7 @@ === Breaking Java Changes === Deprecations +Returning 0 for missing numeric fields in script is deprecated. PR: 29611 === New Features diff --git a/docs/painless/painless-getting-started.asciidoc b/docs/painless/painless-getting-started.asciidoc index 73da36e432f61..ab4ed6a3f8465 100644 --- a/docs/painless/painless-getting-started.asciidoc +++ b/docs/painless/painless-getting-started.asciidoc @@ -121,12 +121,22 @@ GET hockey/_search // CONSOLE [float] -===== Missing and multiple values +===== Missing values -If a document is missing a field `field`, `doc['field']` for this document -will return null. +Currently by default, if a document is missing a numeric field `field`, +`doc['field'].value` returns `0` for this document. This default behaviour +will be changed in the next major version of elasticsearch: +if a document is missing a field `field`, `doc['field']` for this document +will return `null`. You can set a system property +`export ES_JAVA_OPTS="-Des.script.null_for_missing_value=true"' on a node +to make this node's behaviour compatible with the future major version. +Otherwise, every time the node starts a deprecation warning will remind you +about this forthcoming change. -There is also a number of operations designed for numeric fields, + +===== Multiple values + +There is a number of operations designed for numeric fields, if a document has multiple values in such a field: - `doc['field'].min` - gets the minimum value among values diff --git a/modules/lang-painless/build.gradle b/modules/lang-painless/build.gradle index d287d7ee02378..6d759a497f5b2 100644 --- a/modules/lang-painless/build.gradle +++ b/modules/lang-painless/build.gradle @@ -25,6 +25,7 @@ esplugin { } integTestCluster { + systemProperty 'es.script.null_for_missing_value', 'true' module project.project(':modules:mapper-extras') } diff --git a/server/src/main/java/org/elasticsearch/node/Node.java b/server/src/main/java/org/elasticsearch/node/Node.java index 64d176c01fa99..3dde15b710298 100644 --- a/server/src/main/java/org/elasticsearch/node/Node.java +++ b/server/src/main/java/org/elasticsearch/node/Node.java @@ -716,6 +716,10 @@ public void onTimeout(TimeValue timeout) { writePortsFile("transport", transport.boundAddress()); } + if (!ScriptModule.NULL_FOR_MISSING_VALUE) + logger.warn("Script: returning 0 for missing numeric values is deprecated. " + + "Set system property '-Des.script.null_for_missing_value=true' to make behaviour compatible with future major versions."); + logger.info("started"); pluginsService.filterPlugins(ClusterPlugin.class).forEach(ClusterPlugin::onNodeStarted); diff --git a/server/src/main/java/org/elasticsearch/script/ScriptModule.java b/server/src/main/java/org/elasticsearch/script/ScriptModule.java index 727651be6a565..579d63b38b7fe 100644 --- a/server/src/main/java/org/elasticsearch/script/ScriptModule.java +++ b/server/src/main/java/org/elasticsearch/script/ScriptModule.java @@ -27,6 +27,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.elasticsearch.common.Booleans; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.plugins.ScriptPlugin; @@ -52,6 +53,9 @@ public class ScriptModule { ).collect(Collectors.toMap(c -> c.name, Function.identity())); } + public static final boolean NULL_FOR_MISSING_VALUE = + Booleans.parseBoolean(System.getProperty("es.script.null_for_missing_value", "false")); + private final ScriptService scriptService; public ScriptModule(Settings settings, List scriptPlugins) { diff --git a/server/src/main/java/org/elasticsearch/search/lookup/LeafDocLookup.java b/server/src/main/java/org/elasticsearch/search/lookup/LeafDocLookup.java index d1548bd5b5e67..2fcc72eb54e32 100644 --- a/server/src/main/java/org/elasticsearch/search/lookup/LeafDocLookup.java +++ b/server/src/main/java/org/elasticsearch/search/lookup/LeafDocLookup.java @@ -25,6 +25,7 @@ import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MapperService; +import org.elasticsearch.script.ScriptModule; import java.io.IOException; import java.security.AccessController; @@ -92,7 +93,7 @@ public ScriptDocValues run() { } try { boolean docHasValues = scriptValues.setNextDocId(docId); - if (!docHasValues) return null; + if (!docHasValues && ScriptModule.NULL_FOR_MISSING_VALUE) return null; } catch (IOException e) { throw ExceptionsHelper.convertToElastic(e); }