1414import org .elasticsearch .common .util .Maps ;
1515import org .elasticsearch .common .util .concurrent .ConcurrentCollections ;
1616import org .elasticsearch .common .util .set .Sets ;
17+ import org .elasticsearch .core .Nullable ;
1718import org .elasticsearch .core .UpdateForV10 ;
1819import org .elasticsearch .index .VersionType ;
1920import org .elasticsearch .index .mapper .IdFieldMapper ;
2425import org .elasticsearch .script .CtxMap ;
2526import org .elasticsearch .script .ScriptService ;
2627import org .elasticsearch .script .TemplateScript ;
28+ import org .elasticsearch .script .field .WriteField ;
2729
2830import java .time .ZoneOffset ;
2931import java .time .ZonedDateTime ;
@@ -192,6 +194,17 @@ public <T> T getFieldValue(String path, Class<T> clazz) {
192194 */
193195 public <T > T getFieldValue (String path , Class <T > clazz , boolean ignoreMissing ) {
194196 final FieldPath fieldPath = FieldPath .of (path );
197+ WriteField writeField = getWriteField (path );
198+ if (writeField != null ) {
199+ if (writeField .exists () == false ) {
200+ if (ignoreMissing == false ) {
201+ throw new IllegalArgumentException ("no field found for path " + path );
202+ } else {
203+ return null ;
204+ }
205+ }
206+ return cast (path , writeField .get (null ), clazz );
207+ }
195208 Object context = fieldPath .initialContext (this );
196209 ResolveResult result = resolve (fieldPath .pathElements , fieldPath .pathElements .length , path , context );
197210 if (result .wasSuccessful ) {
@@ -257,6 +270,10 @@ public boolean hasField(String path) {
257270 * @throws IllegalArgumentException if the path is null, empty or invalid.
258271 */
259272 public boolean hasField (String path , boolean failOutOfRange ) {
273+ WriteField writeField = getWriteField (path );
274+ if (writeField != null ) {
275+ return writeField .exists ();
276+ }
260277 final FieldPath fieldPath = FieldPath .of (path );
261278 Object context = fieldPath .initialContext (this );
262279 for (int i = 0 ; i < fieldPath .pathElements .length - 1 ; i ++) {
@@ -325,6 +342,14 @@ public void removeField(String path) {
325342 removeField (path , false );
326343 }
327344
345+ @ Nullable
346+ private WriteField getWriteField (String path ) {
347+ if ((path .startsWith ("$('" ) && path .endsWith ("')" ) ) || (path .startsWith ("$(\" " ) && path .endsWith ("\" )" ))) {
348+ return new WriteField (path .substring (3 , path .length () - 2 ), this ::getCtxMap );
349+ }
350+ return null ;
351+ }
352+
328353 /**
329354 * Removes the field identified by the provided path.
330355 *
@@ -333,6 +358,14 @@ public void removeField(String path) {
333358 * @throws IllegalArgumentException if the path is null, empty, or invalid; or if the field doesn't exist (and ignoreMissing is false).
334359 */
335360 public void removeField (String path , boolean ignoreMissing ) {
361+ WriteField writeField = getWriteField (path );
362+ if (writeField != null ) {
363+ if (ignoreMissing == false && writeField .exists () == false ) {
364+ throw new IllegalArgumentException ("no field found for path " + path );
365+ }
366+ writeField .remove ();
367+ return ;
368+ }
336369 final FieldPath fieldPath = FieldPath .of (path );
337370 Object context = fieldPath .initialContext (this );
338371 ResolveResult result = resolve (fieldPath .pathElements , fieldPath .pathElements .length - 1 , path , context );
@@ -548,6 +581,15 @@ public void setFieldValue(String path, Object value, boolean ignoreEmptyValue) {
548581 }
549582
550583 private void setFieldValue (String path , Object value , boolean append , boolean allowDuplicates ) {
584+ WriteField writeField = getWriteField (path );
585+ if (writeField != null ) {
586+ if (append && writeField .exists ()) {
587+ writeField .set (appendValues (writeField .get (null ), value , allowDuplicates ));
588+ } else {
589+ writeField .set (value );
590+ }
591+ return ;
592+ }
551593 final FieldPath fieldPath = FieldPath .of (path );
552594 Object context = fieldPath .initialContext (this );
553595 for (int i = 0 ; i < fieldPath .pathElements .length - 1 ; i ++) {
0 commit comments