Currently, when an object is mapped with `subobjects: false`, trying to ingest a document that has nested objects leads to a mapping exception.

In a couple of occasions, we've been talking about that it would be convenient if Elasticsearch could automatically flatten the fields instead of the client having to know about the `subobjects` setting. This would make `subobjects: false` more of a drop-in replacement that allows for a much easier adoption, without changes in the client.

Note that the `_source` should ideally stay untouched, just the stored fields should be flattened automatically.

Some related issues
* https://github.com/elastic/apm/issues/347
* https://github.com/elastic/elasticsearch/issues/88777
* https://github.com/elastic/package-spec/issues/349
libs/x-content/src/test/java/org/elasticsearch/xcontent/XContentParserTests.java
sub1.put("type", "keyword");
        sub1.put("foo", 17);
        Map<String, Object> properties = new HashMap<>();
        properties.put("sub1", sub1);
        Map<String, Object> f2 = new HashMap<>();
        f2.put("type", "object");
        f2.put("properties", properties);
        Map<String, Object> doc = new HashMap<>();
        doc.put("f1", f1);
        doc.put("f2", f2);
        Map<String, Object> expected = new HashMap<>();
        expected.put("_doc", doc);
        Map<String, Object> i = new HashMap<>();
        i.put("i", expected);
        try (XContentParser parser = createParser(JsonXContent.jsonXContent, source)) {
            XContentParser.Token token = parser.nextToken();
            assertThat(token, equalTo(XContentParser.Token.START_OBJECT));
            Map<String, Object> map = parser.map();
            assertThat(map, equalTo(i));
        }
    }
    private Map<String, String> readMapStrings(String source) throws IOException {
        try (XContentParser parser = createParser(JsonXContent.jsonXContent, source)) {
            XContentParser.Token token = parser.nextToken();
            assertThat(token, equalTo(XContentParser.Token.START_OBJECT));
            token = parser.nextToken();
            assertThat(token, equalTo(XContentParser.Token.FIELD_NAME));
            assertThat(parser.currentName(), equalTo("foo"));
            token = parser.nextToken();
            assertThat(token, equalTo(XContentParser.Token.START_OBJECT));