Skip to content

Commit 375a477

Browse files
authored
Add an ignoreMissing parameter to IngestDocument's removeField method (elastic#125232) (elastic#125260)
1 parent b0411d9 commit 375a477

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
@@ -58,15 +58,9 @@ public IngestDocument execute(IngestDocument document) {
5858
}
5959

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

@@ -75,13 +69,7 @@ private void fieldsToKeepProcessor(IngestDocument document) {
7569
.stream()
7670
.filter(documentField -> IngestDocument.Metadata.isMetadata(documentField) == false)
7771
.filter(documentField -> shouldKeep(documentField, fieldsToKeep, document) == false)
78-
.forEach(documentField -> removeWhenPresent(document, documentField));
79-
}
80-
81-
private static void removeWhenPresent(IngestDocument document, String documentField) {
82-
if (document.hasField(documentField)) {
83-
document.removeField(documentField);
84-
}
72+
.forEach(documentField -> document.removeField(documentField, true));
8573
}
8674

8775
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
@@ -316,15 +316,29 @@ public boolean hasField(String path, boolean failOutOfRange) {
316316

317317
/**
318318
* Removes the field identified by the provided path.
319+
*
319320
* @param path the path of the field to be removed
320321
* @throws IllegalArgumentException if the path is null, empty, invalid or if the field doesn't exist.
321322
*/
322323
public void removeField(String path) {
324+
removeField(path, false);
325+
}
326+
327+
/**
328+
* Removes the field identified by the provided path.
329+
*
330+
* @param path the path of the field to be removed
331+
* @param ignoreMissing The flag to determine whether to throw an exception when `path` is not found in the document.
332+
* @throws IllegalArgumentException if the path is null, empty, or invalid; or if the field doesn't exist (and ignoreMissing is false).
333+
*/
334+
public void removeField(String path, boolean ignoreMissing) {
323335
final FieldPath fieldPath = FieldPath.of(path);
324336
Object context = fieldPath.initialContext(this);
325337
ResolveResult result = resolve(fieldPath.pathElements, fieldPath.pathElements.length - 1, path, context);
326338
if (result.wasSuccessful) {
327339
context = result.resolvedObject;
340+
} else if (ignoreMissing) {
341+
return; // nothing was found, so there's nothing to remove :shrug:
328342
} else {
329343
throw new IllegalArgumentException(result.errorMessage);
330344
}
@@ -335,13 +349,13 @@ public void removeField(String path) {
335349
} else if (context instanceof IngestCtxMap map) { // optimization: handle IngestCtxMap separately from Map
336350
if (map.containsKey(leafKey)) {
337351
map.remove(leafKey);
338-
} else {
352+
} else if (ignoreMissing == false) {
339353
throw new IllegalArgumentException(Errors.notPresent(path, leafKey));
340354
}
341355
} else if (context instanceof Map<?, ?> map) {
342356
if (map.containsKey(leafKey)) {
343357
map.remove(leafKey);
344-
} else {
358+
} else if (ignoreMissing == false) {
345359
throw new IllegalArgumentException(Errors.notPresent(path, leafKey));
346360
}
347361
} else if (context instanceof List<?> list) {
@@ -352,11 +366,13 @@ public void removeField(String path) {
352366
throw new IllegalArgumentException(Errors.notInteger(path, leafKey), e);
353367
}
354368
if (index < 0 || index >= list.size()) {
355-
throw new IllegalArgumentException(Errors.outOfBounds(path, index, list.size()));
369+
if (ignoreMissing == false) {
370+
throw new IllegalArgumentException(Errors.outOfBounds(path, index, list.size()));
371+
}
356372
} else {
357373
list.remove(index);
358374
}
359-
} else {
375+
} else if (ignoreMissing == false) {
360376
throw new IllegalArgumentException(Errors.cannotRemove(path, leafKey, context));
361377
}
362378
}

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)