def _generate_document_section(self, schema_name: str) -> (List[str], StructuredMarqoIndex):
        """
        Generate the document (fields) section of the Vespa schema.

        Returns:
            A tuple of the document section and the StructuredMarqoIndex object.
        """
        document: List[str] = list()
        fields: List[Field] = []
        tensor_fields: List[TensorField] = []

        document.append(f'document {{')

        # ID field
        document.append(f'field {common.FIELD_ID} type string {{')
        document.append('indexing: attribute | summary')
        document.append('attribute: fast-search')
        document.append('rank: filter')
        document.append('}')

        for tensor_field_request in self._index_request.fields:
            field_type = self._get_vespa_type(tensor_field_request.type)
            lexical_field_name = None
            filter_field_name = None

            if FieldFeature.LexicalSearch in tensor_field_request.features:
                field_name = f'{self._FIELD_INDEX_PREFIX}{tensor_field_request.name}'
                document.append(f'field {field_name} type {field_type} {{')
                document.append(f'indexing: index | summary')
                document.append('index: enable-bm25')
                document.append('}')

                lexical_field_name = field_name

            if FieldFeature.Filter in tensor_field_request.features:
                field_name = f'{self._FIELD_FILTER_PREFIX}{tensor_field_request.name}'
                document.append(f'field {field_name} type {field_type} {{')
                document.append('indexing: attribute | summary')
                document.append('attribute: fast-search')
                document.append('rank: filter')
                document.append('}')

                filter_field_name = field_name

            if (
                    FieldFeature.LexicalSearch not in tensor_field_request.features and
                    FieldFeature.Filter not in tensor_field_request.features
            ):
                field_name = tensor_field_request.name
                document.append(f'field {field_name} type {field_type} {{')
                document.append('indexing: summary')
                document.append('}')

            fields.append(
                Field(
                    name=tensor_field_request.name,
                    type=tensor_field_request.type,
                    features=tensor_field_request.features,
                    lexical_field_name=lexical_field_name,
                    filter_field_name=filter_field_name,
                    dependent_fields=tensor_field_request.dependent_fields
                )
            )

        # score modifiers
        if any(FieldFeature.ScoreModifier in f.features for f in self._index_request.fields):
            document.append(
                f'field {common.FIELD_SCORE_MODIFIERS_DOUBLE_LONG} type tensor<double>(p{{}}) {{ indexing: attribute | summary }}',
            )
            document.append(
                f'field {common.FIELD_SCORE_MODIFIERS_FLOAT} type tensor<float>(p{{}}) {{ indexing: attribute | summary }}'
            )

        # tensor fields
        model_dim = self._index_request.model.get_dimension()
        for tensor_field_request in self._index_request.tensor_fields:
            chunks_field_name = f'{self._FIELD_CHUNKS_PREFIX}{tensor_field_request}'
            embedding_field_name = f'{self._FIELD_EMBEDDING_PREFIX}{tensor_field_request}'
            document.append(f'field {chunks_field_name} type array<string> {{')
            document.append('indexing: attribute | summary')
            document.append('}')
            document.append(f'field {embedding_field_name} type tensor<float>(p{{}}, x[{model_dim}]) {{')
            document.append('indexing: attribute | index | summary')
            document.append(
                f'attribute {{ distance-metric: {self._get_distance_metric(self._index_request.distance_metric)} }}')
            document.append('index { hnsw {')
            document.append(f'max-links-per-node: {self._index_request.hnsw_config.m}')
            document.append(f'neighbors-to-explore-at-insert: {self._index_request.hnsw_config.ef_construction}')
            document.append('}}')
            document.append('}')

            tensor_fields.append(
                TensorField(
                    name=tensor_field_request,
                    chunk_field_name=chunks_field_name,
                    embeddings_field_name=embedding_field_name
                )
            )

        # vector count field
        document.append(f'field {common.FIELD_VECTOR_COUNT} type int {{ indexing: attribute | summary }}')

        document.append('}')

        marqo_index = StructuredMarqoIndex(
            name=self._index_request.name,
            schema_name=schema_name,
            model=self._index_request.model,
            normalize_embeddings=self._index_request.normalize_embeddings,
            text_preprocessing=self._index_request.text_preprocessing,
            image_preprocessing=self._index_request.image_preprocessing,
            video_preprocessing=self._index_request.video_preprocessing,
            audio_preprocessing=self._index_request.audio_preprocessing,
            distance_metric=self._index_request.distance_metric,
            vector_numeric_type=self._index_request.vector_numeric_type,
            hnsw_config=self._index_request.hnsw_config,
            marqo_version=self._index_request.marqo_version,
            created_at=self._index_request.created_at,
            updated_at=self._index_request.updated_at,
            fields=fields,
            tensor_fields=tensor_fields,
        )

        return document, marqo_index

        Generate the document (fields) section of the Vespa schema.

        Returns:
            A tuple of the document section and the StructuredMarqoIndex object.
        
src/marqo/core/structured_vespa_index/structured_vespa_schema.py