@@ -799,17 +799,30 @@ private static void parseNonDynamicArray(
799799 String fullPath = context .path ().pathAsText (arrayFieldName );
800800
801801 // Check if we need to record the array source. This only applies to synthetic source.
802+ boolean canRemoveSingleLeafElement = false ;
802803 if (context .canAddIgnoredField ()) {
803- boolean objectRequiresStoringSource = mapper instanceof ObjectMapper objectMapper
804- && (getSourceKeepMode (context , objectMapper .sourceKeepMode ()) == Mapper .SourceKeepMode .ALL
805- || (getSourceKeepMode (context , objectMapper .sourceKeepMode ()) == Mapper .SourceKeepMode .ARRAYS
806- && objectMapper instanceof NestedObjectMapper == false ));
807- boolean fieldWithFallbackSyntheticSource = mapper instanceof FieldMapper fieldMapper
808- && fieldMapper .syntheticSourceMode () == FieldMapper .SyntheticSourceMode .FALLBACK ;
809- boolean fieldWithStoredArraySource = mapper instanceof FieldMapper fieldMapper
810- && getSourceKeepMode (context , fieldMapper .sourceKeepMode ()) != Mapper .SourceKeepMode .NONE ;
804+ Mapper .SourceKeepMode mode = Mapper .SourceKeepMode .NONE ;
805+ boolean objectWithFallbackSyntheticSource = false ;
806+ if (mapper instanceof ObjectMapper objectMapper ) {
807+ mode = getSourceKeepMode (context , objectMapper .sourceKeepMode ());
808+ objectWithFallbackSyntheticSource = (mode == Mapper .SourceKeepMode .ALL
809+ || (mode == Mapper .SourceKeepMode .ARRAYS && objectMapper instanceof NestedObjectMapper == false ));
810+ }
811+ boolean fieldWithFallbackSyntheticSource = false ;
812+ boolean fieldWithStoredArraySource = false ;
813+ if (mapper instanceof FieldMapper fieldMapper ) {
814+ mode = getSourceKeepMode (context , fieldMapper .sourceKeepMode ());
815+ fieldWithFallbackSyntheticSource = fieldMapper .syntheticSourceMode () == FieldMapper .SyntheticSourceMode .FALLBACK ;
816+ fieldWithStoredArraySource = mode != Mapper .SourceKeepMode .NONE ;
817+ }
811818 boolean copyToFieldHasValuesInDocument = context .isWithinCopyTo () == false && context .isCopyToDestinationField (fullPath );
812- if (objectRequiresStoringSource
819+
820+ canRemoveSingleLeafElement = mapper instanceof FieldMapper
821+ && mode == Mapper .SourceKeepMode .ARRAYS
822+ && fieldWithFallbackSyntheticSource == false
823+ && copyToFieldHasValuesInDocument == false ;
824+
825+ if (objectWithFallbackSyntheticSource
813826 || fieldWithFallbackSyntheticSource
814827 || fieldWithStoredArraySource
815828 || copyToFieldHasValuesInDocument ) {
@@ -829,20 +842,28 @@ private static void parseNonDynamicArray(
829842
830843 XContentParser parser = context .parser ();
831844 XContentParser .Token token ;
845+ int elements = 0 ;
832846 while ((token = parser .nextToken ()) != XContentParser .Token .END_ARRAY ) {
833847 if (token == XContentParser .Token .START_OBJECT ) {
848+ elements = Integer .MAX_VALUE ;
834849 parseObject (context , lastFieldName );
835850 } else if (token == XContentParser .Token .START_ARRAY ) {
851+ elements = Integer .MAX_VALUE ;
836852 parseArray (context , lastFieldName );
837853 } else if (token == XContentParser .Token .VALUE_NULL ) {
854+ elements ++;
838855 parseNullValue (context , lastFieldName );
839856 } else if (token == null ) {
840857 throwEOFOnParseArray (arrayFieldName , context );
841858 } else {
842859 assert token .isValue ();
860+ elements ++;
843861 parseValue (context , lastFieldName );
844862 }
845863 }
864+ if (elements <= 1 && canRemoveSingleLeafElement ) {
865+ context .removeLastIgnoredField (fullPath );
866+ }
846867 postProcessDynamicArrayMapping (context , lastFieldName );
847868 }
848869
0 commit comments