Skip to content

Commit 935e9e3

Browse files
committed
Add an ignoreMissing parameter to IngestDocument's removeField method (elastic#125232)
1 parent 3942ed7 commit 935e9e3

File tree

3 files changed

+41
-20
lines changed

3 files changed

+41
-20
lines changed

modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/RemoveProcessor.java

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,9 @@ public IngestDocument execute(IngestDocument document) {
5959
}
6060

6161
private void fieldsToRemoveProcessor(IngestDocument document) {
62-
// micro-optimization note: actual for-each loops here rather than a .forEach because it happens to be ~5% faster in benchmarks
63-
if (ignoreMissing) {
64-
for (TemplateScript.Factory field : fieldsToRemove) {
65-
removeWhenPresent(document, document.renderTemplate(field));
66-
}
67-
} else {
68-
for (TemplateScript.Factory field : fieldsToRemove) {
69-
document.removeField(document.renderTemplate(field));
70-
}
62+
// micro-optimization note: actual for-each loop here rather than a .forEach because it happens to be ~5% faster in benchmarks
63+
for (TemplateScript.Factory field : fieldsToRemove) {
64+
document.removeField(document.renderTemplate(field), ignoreMissing);
7165
}
7266
}
7367

@@ -76,13 +70,7 @@ private void fieldsToKeepProcessor(IngestDocument document) {
7670
.stream()
7771
.filter(documentField -> IngestDocument.Metadata.isMetadata(documentField) == false)
7872
.filter(documentField -> shouldKeep(documentField, fieldsToKeep, document) == false)
79-
.forEach(documentField -> removeWhenPresent(document, documentField));
80-
}
81-
82-
private static void removeWhenPresent(IngestDocument document, String documentField) {
83-
if (document.hasField(documentField)) {
84-
document.removeField(documentField);
85-
}
73+
.forEach(documentField -> document.removeField(documentField, true));
8674
}
8775

8876
static boolean shouldKeep(String documentField, List<TemplateScript.Factory> fieldsToKeep, IngestDocument document) {

server/src/main/java/org/elasticsearch/ingest/IngestDocument.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -317,15 +317,29 @@ public boolean hasField(String path, boolean failOutOfRange) {
317317

318318
/**
319319
* Removes the field identified by the provided path.
320+
*
320321
* @param path the path of the field to be removed
321322
* @throws IllegalArgumentException if the path is null, empty, invalid or if the field doesn't exist.
322323
*/
323324
public void removeField(String path) {
325+
removeField(path, false);
326+
}
327+
328+
/**
329+
* Removes the field identified by the provided path.
330+
*
331+
* @param path the path of the field to be removed
332+
* @param ignoreMissing The flag to determine whether to throw an exception when `path` is not found in the document.
333+
* @throws IllegalArgumentException if the path is null, empty, or invalid; or if the field doesn't exist (and ignoreMissing is false).
334+
*/
335+
public void removeField(String path, boolean ignoreMissing) {
324336
final FieldPath fieldPath = FieldPath.of(path);
325337
Object context = fieldPath.initialContext(this);
326338
ResolveResult result = resolve(fieldPath.pathElements, fieldPath.pathElements.length - 1, path, context);
327339
if (result.wasSuccessful) {
328340
context = result.resolvedObject;
341+
} else if (ignoreMissing) {
342+
return; // nothing was found, so there's nothing to remove :shrug:
329343
} else {
330344
throw new IllegalArgumentException(result.errorMessage);
331345
}
@@ -336,13 +350,13 @@ public void removeField(String path) {
336350
} else if (context instanceof IngestCtxMap map) { // optimization: handle IngestCtxMap separately from Map
337351
if (map.containsKey(leafKey)) {
338352
map.remove(leafKey);
339-
} else {
353+
} else if (ignoreMissing == false) {
340354
throw new IllegalArgumentException(Errors.notPresent(path, leafKey));
341355
}
342356
} else if (context instanceof Map<?, ?> map) {
343357
if (map.containsKey(leafKey)) {
344358
map.remove(leafKey);
345-
} else {
359+
} else if (ignoreMissing == false) {
346360
throw new IllegalArgumentException(Errors.notPresent(path, leafKey));
347361
}
348362
} else if (context instanceof List<?> list) {
@@ -353,11 +367,13 @@ public void removeField(String path) {
353367
throw new IllegalArgumentException(Errors.notInteger(path, leafKey), e);
354368
}
355369
if (index < 0 || index >= list.size()) {
356-
throw new IllegalArgumentException(Errors.outOfBounds(path, index, list.size()));
370+
if (ignoreMissing == false) {
371+
throw new IllegalArgumentException(Errors.outOfBounds(path, index, list.size()));
372+
}
357373
} else {
358374
list.remove(index);
359375
}
360-
} else {
376+
} else if (ignoreMissing == false) {
361377
throw new IllegalArgumentException(Errors.cannotRemove(path, leafKey, context));
362378
}
363379
}

server/src/test/java/org/elasticsearch/ingest/IngestDocumentTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,23 @@ public void testRemoveField() {
850850
assertThat(document.getIngestMetadata().size(), equalTo(0));
851851
}
852852

853+
public void testRemoveFieldIgnoreMissing() {
854+
document.removeField("foo", randomBoolean());
855+
assertThat(document.getSourceAndMetadata().size(), equalTo(10));
856+
assertThat(document.getSourceAndMetadata().containsKey("foo"), equalTo(false));
857+
document.removeField("_index", randomBoolean());
858+
assertThat(document.getSourceAndMetadata().size(), equalTo(9));
859+
assertThat(document.getSourceAndMetadata().containsKey("_index"), equalTo(false));
860+
861+
// if ignoreMissing is false, we throw an exception for values that aren't found
862+
IllegalArgumentException e;
863+
e = expectThrows(IllegalArgumentException.class, () -> document.removeField("fizz.some.nonsense", false));
864+
assertThat(e.getMessage(), is("field [some] not present as part of path [fizz.some.nonsense]"));
865+
866+
// but no exception is thrown if ignoreMissing is true
867+
document.removeField("fizz.some.nonsense", true);
868+
}
869+
853870
public void testRemoveInnerField() {
854871
document.removeField("fizz.buzz");
855872
assertThat(document.getSourceAndMetadata().size(), equalTo(11));

0 commit comments

Comments
 (0)