def from_vespa_document(cls, document: Dict, marqo_index: SemiStructuredMarqoIndex) -> "SemiStructuredVespaDocument":
        """
        Instantiate an SemiStructuredVespaDocument from a Vespa document.
        Used in get_document_by_id or get_documents_by_ids
        """
        fields = document.get(_VESPA_DOC_FIELDS, {})
        tensor_fields = {}
        text_fields = {}
        string_arrays_dict = {}

        tensor_subfield_map = marqo_index.tensor_subfield_map
        lexical_field_map = marqo_index.lexical_field_map
        field_map = marqo_index.field_map
        string_array_field_map = marqo_index.string_array_field_name_to_string_array_field_map
        string_array_prefix_length = len(common.STRING_ARRAY + '_')

        for field_name, field_value in fields.items():
            if field_name in tensor_subfield_map:
                tensor_fields[field_name] = field_value
            elif field_name in lexical_field_map:
                # Lexical fields are returned with prefixed name from get_by_ids
                text_field_name = lexical_field_map[field_name].name
                text_fields[text_field_name] = field_value
            elif field_name in field_map:
                # Lexical fields are returned with original name from search
                text_fields[field_name] = field_value
            elif field_name in string_array_field_map:
                # Handle string arrays separately
                # In case of indexes which  support partial updates (i.e indexes created with Marqo version post 2.16.0), string arrays are stored in Vespa like
                # 'marqo__string_array_field_name_1': ['element1', 'element2', ...]
                # 'marqo__string_array_field_name_2': ['element3', 'element4', ...]
                # Here we will collect all such string array fields and put them in string_arrays_dict, which will later be used  to construct the SemiStructuredVespaDocument object.
                string_array_field_key = field_name[string_array_prefix_length:]
                string_arrays_dict[string_array_field_key] = field_value

        # model_construct assumes all the fields are validated. We construct each field manually so the validation
        # (which in this case is just simple type check) is not necessary.
        return cls.model_construct(
            id=document[_VESPA_DOC_ID],
            fixed_fields=SemiStructuredVespaDocumentFields(**fields),
            tensor_fields=tensor_fields,
            text_fields=text_fields,
            string_array_fields=string_arrays_dict,
            index_supports_partial_updates=marqo_index.index_supports_partial_updates)

        Instantiate an SemiStructuredVespaDocument from a Vespa document.
        Used in get_document_by_id or get_documents_by_ids
        
src/marqo/core/semi_structured_vespa_index/semi_structured_document.py