Skip to content

Commit 7f27952

Browse files
committed
Fixes elastic#4047 - Empty objects are not stored in _source when an include/exclude list is present
1 parent 3925181 commit 7f27952

File tree

2 files changed

+105
-18
lines changed

2 files changed

+105
-18
lines changed

src/main/java/org/elasticsearch/common/xcontent/support/XContentMapValues.java

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,7 @@ private static void filter(Map<String, Object> map, Map<String, Object> into, St
153153
}
154154
sb.append(key);
155155
String path = sb.toString();
156-
boolean excluded = false;
157-
for (String exclude : excludes) {
158-
if (Regex.simpleMatch(exclude, path)) {
159-
excluded = true;
160-
break;
161-
}
162-
}
163-
if (excluded) {
156+
if (Regex.simpleMatch(excludes, path)) {
164157
sb.setLength(mark);
165158
continue;
166159
}
@@ -205,12 +198,16 @@ private static void filter(Map<String, Object> map, Map<String, Object> into, St
205198
}
206199

207200

208-
if (entry.getValue() instanceof Map && !((Map<String, Object>) entry.getValue()).isEmpty()) {
201+
if (entry.getValue() instanceof Map) {
209202
Map<String, Object> innerInto = Maps.newHashMap();
210-
// if we had an exact match, we want give deeper excludes their chance
211-
filter((Map<String, Object>) entry.getValue(), innerInto, exactIncludeMatch ? Strings.EMPTY_ARRAY : includes, excludes, sb);
212-
if (!innerInto.isEmpty()) {
203+
if (exactIncludeMatch && ((Map<String, Object>) entry.getValue()).isEmpty() && !Regex.simpleMatch(excludes, path + '.')) {
213204
into.put(entry.getKey(), innerInto);
205+
} else {
206+
// if we had an exact match, we want give deeper excludes their chance
207+
filter((Map<String, Object>) entry.getValue(), innerInto, exactIncludeMatch ? Strings.EMPTY_ARRAY : includes, excludes, sb);
208+
if (!innerInto.isEmpty()) {
209+
into.put(entry.getKey(), innerInto);
210+
}
214211
}
215212
} else if (entry.getValue() instanceof List) {
216213
List<Object> list = (List<Object>) entry.getValue();

src/test/java/org/elasticsearch/common/xcontent/support/XContentMapValuesTests.java

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ public void filterWithEmptyIncludesExcludes() {
370370
}
371371

372372
@Test
373-
public void testThatFilteringWithEmptyObjectAndExclusionWorks() throws Exception {
373+
public void testThatFilterIncludesEmptyObjectWhenUsingExcludes() throws Exception {
374374
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
375375
.startObject("obj")
376376
.endObject()
@@ -383,7 +383,7 @@ public void testThatFilteringWithEmptyObjectAndExclusionWorks() throws Exception
383383
}
384384

385385
@Test
386-
public void testThatFilterIncludesEmptyObjectsWithoutExcludedProperties() throws Exception {
386+
public void testThatFilterOmitsEmptyObjectWithExcludedProperties() throws Exception {
387387
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
388388
.startObject("obj")
389389
.endObject()
@@ -392,9 +392,20 @@ public void testThatFilterIncludesEmptyObjectsWithoutExcludedProperties() throws
392392
Tuple<XContentType, Map<String, Object>> mapTuple = XContentHelper.convertToMap(builder.bytes(), true);
393393
Map<String, Object> filteredSource = XContentMapValues.filter(mapTuple.v2(), Strings.EMPTY_ARRAY, new String[]{"obj.*"});
394394

395-
assertThat(filteredSource.size(), equalTo(1));
396-
assertThat(filteredSource, hasKey("obj"));
397-
assertThat(((Map) filteredSource.get("obj")).size(), equalTo(0));
395+
assertThat(filteredSource.size(), equalTo(0));
396+
}
397+
398+
@Test
399+
public void testThatFilterIncludesEmptyObjectWithExcludedProperty() throws Exception {
400+
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
401+
.startObject("obj")
402+
.endObject()
403+
.endObject();
404+
405+
Tuple<XContentType, Map<String, Object>> mapTuple = XContentHelper.convertToMap(builder.bytes(), true);
406+
Map<String, Object> filteredSource = XContentMapValues.filter(mapTuple.v2(), Strings.EMPTY_ARRAY, new String[]{"obj.f1"});
407+
408+
assertThat(mapTuple.v2(), equalTo(filteredSource));
398409
}
399410

400411
@Test
@@ -430,7 +441,7 @@ public void testThatFilterIncludesObjectsWithSomeExcludedProperties() throws Exc
430441
}
431442

432443
@Test
433-
public void testThatFilteringWithEmptyObjectAndInclusionWorks() throws Exception {
444+
public void testThatFilterIncludesEmptyObjectWhenUsingIncludes() throws Exception {
434445
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
435446
.startObject("obj")
436447
.endObject()
@@ -486,4 +497,83 @@ public void testThatFilterIncludesObjectsWithSomeIncludedProperties() throws Exc
486497
assertThat(((Map) filteredSource.get("obj")).size(), equalTo(1));
487498
assertThat(((Map<String, Object>) filteredSource.get("obj")), hasKey("f2"));
488499
}
500+
501+
@Test
502+
public void testFilterWithIncludesAndExcludes() throws Exception {
503+
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
504+
.startObject("obj1")
505+
.endObject()
506+
.startObject("obj2")
507+
.endObject()
508+
.endObject();
509+
510+
Tuple<XContentType, Map<String, Object>> mapTuple = XContentHelper.convertToMap(builder.bytes(), true);
511+
Map<String, Object> filteredSource = XContentMapValues.filter(mapTuple.v2(), new String[]{"obj1.*"}, new String[]{"obj2.*"});
512+
513+
assertThat(filteredSource.size(), equalTo(0));
514+
}
515+
516+
@Test
517+
public void testFilterExcludesWithNestedObjects() throws Exception {
518+
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
519+
.startObject("obj1")
520+
.startObject("obj2")
521+
.endObject()
522+
.endObject()
523+
.endObject();
524+
525+
Tuple<XContentType, Map<String, Object>> mapTuple = XContentHelper.convertToMap(builder.bytes(), true);
526+
Map<String, Object> filteredSource = XContentMapValues.filter(mapTuple.v2(), Strings.EMPTY_ARRAY, new String[]{"*.obj2.*"});
527+
528+
assertThat(filteredSource.size(), equalTo(0));
529+
}
530+
531+
@Test
532+
public void testFilterOmitsObjectWithNestedExcludedObjects() throws Exception {
533+
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
534+
.startObject("obj1")
535+
.startObject("obj2")
536+
.endObject()
537+
.endObject()
538+
.endObject();
539+
540+
Tuple<XContentType, Map<String, Object>> mapTuple = XContentHelper.convertToMap(builder.bytes(), true);
541+
Map<String, Object> filteredSource = XContentMapValues.filter(mapTuple.v2(), Strings.EMPTY_ARRAY, new String[]{"*.obj2"});
542+
543+
assertThat(filteredSource.size(), equalTo(0));
544+
}
545+
546+
@Test
547+
public void testFilterOmitsObjectWithNestedExcludedObject() throws Exception {
548+
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
549+
.startObject("obj1")
550+
.startObject("obj2")
551+
.endObject()
552+
.endObject()
553+
.endObject();
554+
555+
Tuple<XContentType, Map<String, Object>> mapTuple = XContentHelper.convertToMap(builder.bytes(), true);
556+
Map<String, Object> filteredSource = XContentMapValues.filter(mapTuple.v2(), Strings.EMPTY_ARRAY, new String[]{"*.obj2"});
557+
558+
assertThat(filteredSource.size(), equalTo(0));
559+
}
560+
561+
@Test
562+
public void testFilterIncludesObjectWithNestedIncludedObject() throws Exception {
563+
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
564+
.startObject("obj1")
565+
.startObject("obj2")
566+
.endObject()
567+
.endObject()
568+
.endObject();
569+
570+
Tuple<XContentType, Map<String, Object>> mapTuple = XContentHelper.convertToMap(builder.bytes(), true);
571+
Map<String, Object> filteredSource = XContentMapValues.filter(mapTuple.v2(), new String[]{"*.obj2"}, Strings.EMPTY_ARRAY);
572+
573+
assertThat(filteredSource.size(), equalTo(1));
574+
assertThat(filteredSource, hasKey("obj1"));
575+
assertThat(((Map) filteredSource.get("obj1")).size(), equalTo(1));
576+
assertThat(((Map<String, Object>) filteredSource.get("obj1")), hasKey("obj2"));
577+
assertThat(((Map) ((Map) filteredSource.get("obj1")).get("obj2")).size(), equalTo(0));
578+
}
489579
}

0 commit comments

Comments
 (0)