Skip to content

Commit e45f7bb

Browse files
Limit the number of nested documents
Add an index level setting `index.mapping.nested_objects.limit` to control the number of nested json objects that can be in a single document across all fields. Defaults to 10000. Throw an error if the number of created nested documents exceed this limit during the parsing of a document. Closes #26962
1 parent a433f7d commit e45f7bb

File tree

2 files changed

+22
-15
lines changed

2 files changed

+22
-15
lines changed

core/src/test/java/org/elasticsearch/index/mapper/NestedObjectMapperTests.java

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -525,35 +525,42 @@ public void testParentObjectMapperAreNested() throws Exception {
525525
}
526526

527527
public void testLimitNestedDocsDefaultSettings() throws Exception{
528-
MapperService mapperService = createIndex("test1", Settings.builder().build()).mapperService();
528+
Settings settings = Settings.builder().build();
529+
MapperService mapperService = createIndex("test1", settings).mapperService();
529530
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
530531
.startObject("nested1").field("type", "nested").endObject()
531532
.endObject().endObject().endObject().string();
532533
DocumentMapper docMapper = mapperService.documentMapperParser().parse("type", new CompressedXContent(mapping));
534+
long defaultMaxNoNestedDocs = MapperService.INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING.get(settings);
533535

534-
// parsing a doc with 3 nested objects succeeds
536+
// parsing a doc with No. nested objects > defaultMaxNoNestedDocs fails
535537
XContentBuilder docBuilder = XContentFactory.jsonBuilder();
536538
docBuilder.startObject();
537539
{
538540
docBuilder.startArray("nested1");
539541
{
540-
docBuilder.startObject().field("field1", "11").field("field2", "21").endObject();
541-
docBuilder.startObject().field("field1", "12").field("field2", "22").endObject();
542-
docBuilder.startObject().field("field1", "13").field("field2", "23").endObject();
542+
for(int i=0; i<=defaultMaxNoNestedDocs; i++) {
543+
docBuilder.startObject().field("f", i).endObject();
544+
}
543545
}
544546
docBuilder.endArray();
545547
}
546548
docBuilder.endObject();
547549
SourceToParse source1 = SourceToParse.source("test1", "type", "1", docBuilder.bytes(), XContentType.JSON);
548-
ParsedDocument doc = docMapper.parse(source1);
549-
assertThat(doc.docs().size(), equalTo(4));
550+
MapperParsingException e = expectThrows(MapperParsingException.class, () -> docMapper.parse(source1));
551+
assertEquals(
552+
"The number of nested documents has exceeded the allowed limit of [" + defaultMaxNoNestedDocs
553+
+ "]. This limit can be set by changing the [" + MapperService.INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING.getKey()
554+
+ "] index level setting.",
555+
e.getMessage()
556+
);
550557
}
551558

552559
public void testLimitNestedDocs() throws Exception{
553560
// setting limit to allow only two nested objects in the whole doc
554-
long nested_docs_limit = 2L;
561+
long maxNoNestedDocs = 2L;
555562
MapperService mapperService = createIndex("test1", Settings.builder()
556-
.put(MapperService.INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING.getKey(), nested_docs_limit).build()).mapperService();
563+
.put(MapperService.INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING.getKey(), maxNoNestedDocs).build()).mapperService();
557564
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
558565
.startObject("nested1").field("type", "nested").endObject()
559566
.endObject().endObject().endObject().string();
@@ -591,7 +598,7 @@ public void testLimitNestedDocs() throws Exception{
591598
SourceToParse source2 = SourceToParse.source("test1", "type", "2", docBuilder2.bytes(), XContentType.JSON);
592599
MapperParsingException e = expectThrows(MapperParsingException.class, () -> docMapper.parse(source2));
593600
assertEquals(
594-
"The number of nested documents has exceeded the allowed limit of [" + nested_docs_limit
601+
"The number of nested documents has exceeded the allowed limit of [" + maxNoNestedDocs
595602
+ "]. This limit can be set by changing the [" + MapperService.INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING.getKey()
596603
+ "] index level setting.",
597604
e.getMessage()
@@ -600,9 +607,9 @@ public void testLimitNestedDocs() throws Exception{
600607

601608
public void testLimitNestedDocsMultipleNestedFields() throws Exception{
602609
// setting limit to allow only two nested objects in the whole doc
603-
long nested_docs_limit = 2L;
610+
long maxNoNestedDocs = 2L;
604611
MapperService mapperService = createIndex("test1", Settings.builder()
605-
.put(MapperService.INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING.getKey(), nested_docs_limit).build()).mapperService();
612+
.put(MapperService.INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING.getKey(), maxNoNestedDocs).build()).mapperService();
606613
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
607614
.startObject("nested1").field("type", "nested").endObject()
608615
.startObject("nested2").field("type", "nested").endObject()
@@ -650,7 +657,7 @@ public void testLimitNestedDocsMultipleNestedFields() throws Exception{
650657
SourceToParse source2 = SourceToParse.source("test1", "type", "2", docBuilder2.bytes(), XContentType.JSON);
651658
MapperParsingException e = expectThrows(MapperParsingException.class, () -> docMapper.parse(source2));
652659
assertEquals(
653-
"The number of nested documents has exceeded the allowed limit of [" + nested_docs_limit
660+
"The number of nested documents has exceeded the allowed limit of [" + maxNoNestedDocs
654661
+ "]. This limit can be set by changing the [" + MapperService.INDEX_MAPPING_NESTED_DOCS_LIMIT_SETTING.getKey()
655662
+ "] index level setting.",
656663
e.getMessage()

rest-api-spec/src/main/resources/rest-api-spec/test/create/70_nested.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ setup:
1616
"Indexing a doc with No. nested objects less or equal to index.mapping.nested_objects.limit should succeed":
1717
- skip:
1818
version: " - 6.99.99"
19-
reason: index.mapping.nested_objects setting was introduced from this version
19+
reason: index.mapping.nested_objects setting has been added in 7.0.0
2020
- do:
2121
create:
2222
index: test_1
@@ -30,7 +30,7 @@ setup:
3030
"Indexing a doc with No. nested objects more than index.mapping.nested_objects.limit should fail":
3131
- skip:
3232
version: " - 6.99.99"
33-
reason: index.mapping.nested_objects setting was introduced from this version
33+
reason: index.mapping.nested_objects setting has been added in 7.0.0
3434
- do:
3535
catch: /The number of nested documents has exceeded the allowed limit of \[2\]. This limit can be set by changing the \[index.mapping.nested_objects.limit\] index level setting\./
3636
create:

0 commit comments

Comments
 (0)