

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Enriquecimiento de sus documentos durante la ingesta
<a name="custom-document-enrichment"></a>

**nota**  
La compatibilidad de características varía según el tipo de índice y la API de búsqueda que se use. Para comprobar si esta característica es compatible con el tipo de índice y la API de búsqueda que usa, consulte [Tipos de índices](https://docs.aws.amazon.com/kendra/latest/dg/hiw-index-types.html).

Puede modificar el contenido y los campos de metadatos o atributos del documento durante el proceso de ingesta de documentos. Con Amazon Kendra la función de *enriquecimiento de documentos personalizado*, puede crear, modificar o eliminar los atributos y el contenido del documento al ingerir sus documentos. Amazon Kendra Esto significa que puedes manipular e ingerir sus datos según lo necesite.

Esta característica otorga el control sobre cómo se tratan e ingieren sus documentos en Amazon Kendra. Por ejemplo, puedes eliminar la información de identificación personal de los metadatos del documento mientras los ingieres. Amazon Kendra

Otra forma de utilizar esta función es invocar una función Lambda para ejecutar el reconocimiento óptico de caracteres (OCR) AWS Lambda en las imágenes, la traducción del texto y otras tareas para preparar los datos para su búsqueda o análisis. Por ejemplo, puede invocar una función para ejecutar OCR en imágenes. La función podría interpretar el texto de las imágenes y tratar cada imagen como un documento textual. Una empresa que recibe encuestas de clientes enviadas por correo y las almacena como imágenes, podría ingerirlas como documentos textuales en Amazon Kendra. A continuación, la empresa puede buscar información valiosa de la encuesta de clientes en Amazon Kendra.

Puede utilizar operaciones básicas para aplicarlas como primer análisis de los datos y, a continuación, utilizar una función de Lambda para aplicar operaciones más complejas a los datos. Por ejemplo, puede utilizar una operación básica para eliminar simplemente todos los valores del campo de metadatos del documento “Customer\$1ID” y, a continuación, aplicar una función de Lambda para extraer texto de las imágenes del texto en los documentos.

## Cómo funciona Custom Document Enrichment
<a name="how-custom-document-enrichment-works"></a>

El proceso general de Custom Document Enrichment es el siguiente:

1. El enriquecimiento de documentos personalizado se configura al crear o actualizar la fuente de datos, o al indexar los documentos directamente en ella. Amazon Kendra

1. Amazon Kendra aplica configuraciones en línea o lógica básica para modificar los datos. Para obtener más información, consulte [Operaciones básicas para cambiar los metadatos](#basic-data-maniplation).

1. Si opta por configurar la manipulación avanzada de datos, Amazon Kendra puede aplicarla a sus documentos originales sin procesar o a los documentos estructurados y analizados. Para obtener más información, consulte [Funciones de Lambda: extraer y cambiar metadatos o contenido](#advanced-data-manipulation).

1. Los documentos alterados se incorporan a ellos. Amazon Kendra

En cualquier momento de este proceso, si la configuración no es válida, Amazon Kendra arroja un error.

Cuando llama [CreateDataSource](https://docs.aws.amazon.com/kendra/latest/APIReference/API_CreateDataSource.html)o [BatchPutDocument](https://docs.aws.amazon.com/kendra/latest/APIReference/API_BatchPutDocument.html) APIsproporciona su configuración personalizada de enriquecimiento de documentos. [UpdateDataSource](https://docs.aws.amazon.com/kendra/latest/APIReference/API_UpdateDataSource.html) Si se llama a `BatchPutDocument`, se debe configurar Custom Document Enrichment con cada solicitud. Si utiliza la consola, seleccione el índice y, a continuación, seleccione **Document enrichments** (Enriquecimientos de documentos) para configurar Custom Document Enrichment.

Si usa **Enriquecimientos de documento** en la consola, puede elegir configurar solo las operaciones básicas o solo las funciones de Lambda o ambas, del mismo modo que puede usar la API. Puede seleccionar **Siguiente** en los pasos de la consola para elegir no configurar las operaciones básicas y solo las funciones de Lambda, incluida la opción de aplicarlas a los datos originales (antes de la extracción) o estructurados (después de la extracción). Solo puede guardar las configuraciones si completa todos los pasos de la consola. Las configuraciones de sus documentos no se guardan si no completa todos los pasos.

## Operaciones básicas para cambiar los metadatos
<a name="basic-data-maniplation"></a>

Puede manipular los campos y el contenido del documento mediante la lógica básica. Esto incluye la eliminación de valores de un campo, la modificación de los valores de un campo mediante una condición o la creación de un campo. Para manipulaciones avanzadas que van más allá de lo que puedes manipular con la lógica básica, invoque una función Lambda. Para obtener más información, consulte [Funciones de Lambda: extraer y cambiar metadatos o contenido](#advanced-data-manipulation).

Para aplicar la lógica básica, especifique el campo de destino que desea manipular con el [DocumentAttributeTarget](https://docs.aws.amazon.com/kendra/latest/APIReference/API_DocumentAttributeTarget.html)objeto. Proporcione la clave de atributo. Por ejemplo, la clave “Department” es un campo o atributo que contiene todos los nombres de departamento asociados a los documentos. También puede especificar un valor que se utilizará en el campo de destino si se cumple una condición determinada. La condición se establece con el [DocumentAttributeCondition](https://docs.aws.amazon.com/kendra/latest/APIReference/API_DocumentAttributeCondition.html)objeto. Por ejemplo, si el campo “source\$1URI” contiene “financiero” en su valor URI, rellene previamente el campo de destino “Department” con el valor objetivo “Finance” del documento. También puede eliminar los valores del atributo del documento de destino.

Para aplicar la lógica básica mediante la consola, seleccione el índice y, a continuación, seleccione **Document enrichments**(Enriquecimiento de documentos) en el menú de navegación. Vaya a **Configurar operaciones básicas** para aplicar manipulaciones básicas a los campos y el contenido del documento.

A continuación se muestra un ejemplo del uso de la lógica básica para eliminar todos los números de identificación de clientes del campo del documento denominado “Customer\$1ID”.

**Ejemplo 1: Eliminación de números de identificación de clientes asociados a los documentos**

Datos antes de aplicar la manipulación básica.


| **Document\$1ID** | **Body\$1Text** | **Customer\$1ID** | 
| --- | --- | --- | 
| 1 | Lorem Ipsum. | CID1234 | 
| 2 | Lorem Ipsum. | CID1235 | 
| 3 | Lorem Ipsum. | CID1236 | 

Datos después de aplicar la manipulación básica.


| **Document\$1ID** | **Body\$1Text** | **Customer\$1ID** | 
| --- | --- | --- | 
| 1 | Lorem Ipsum. |   | 
| 2 | Lorem Ipsum. |   | 
| 3 | Lorem Ipsum. |   | 

A continuación se muestra un ejemplo de uso de la lógica básica para crear un campo denominado “Department” y rellenar previamente este campo con los nombres de departamento en función de la información del campo “Source\$1URI”. Por ejemplo, si el campo “source\$1URI” contiene “financial” en su valor URI, rellene previamente el campo de destino “Department” con el valor objetivo “Finance” para el documento.

**Ejemplo 2: Crear el campo “Department” y rellenarlo previamente con nombres de departamento asociados a los documentos mediante una condición.**

Datos antes de aplicar la manipulación básica.


| **Document\$1ID** | **Body\$1Text** | **URI de origen** | 
| --- | --- | --- | 
| 1 | Lorem Ipsum. | financial/1 | 
| 2 | Lorem Ipsum. | financial/2 | 
| 3 | Lorem Ipsum. | financial/3 | 

Datos después de aplicar la manipulación básica.


| **Document\$1ID** | **Body\$1Text** | **URI de origen** | **Department** | 
| --- | --- | --- | --- | 
| 1 | Lorem Ipsum. | financial/1 | Finance | 
| 2 | Lorem Ipsum. | financial/2 | Finanzas | 
| 3 | Lorem Ipsum. | financial/3 | Finanzas | 

**nota**  
Amazon Kendra no puede crear un campo de documento de destino si aún no está creado como campo de índice. Después de crear el campo de indexación, puede crear un campo de documento utilizando`DocumentAttributeTarget`. Amazon Kendra a continuación, asigna el campo de metadatos del documento recién creado a su campo de índice.

El código siguiente es un ejemplo de configuración de la manipulación básica de datos para eliminar los números de identificación de clientes asociados a los documentos.

------
#### [ Console ]

**Para configurar la manipulación básica de datos para eliminar números de identificación de clientes**

1. En el panel de navegación izquierdo, en **Indexes** (Índices), seleccione **Document enrichments** (Enriquecimiento de documentos) y luego seleccione **Add document enrichment** (Añadir enriquecimiento de documentos).

1. En la página **Configurar operaciones básicas**, elija en el menú desplegable el origen de datos que desea modificar los campos de los documentos y el contenido. A continuación, elija en el menú desplegable el nombre del campo de documento “Customer\$1ID”, seleccione en el menú desplegable el nombre del campo de índice “Customer\$1ID” y seleccione en el menú desplegable la acción de destino **Eliminar**. A continuación, seleccione **Add basic operation** (Añadir operación básica).

------
#### [ CLI ]

**Para configurar la manipulación básica de datos para eliminar números de identificación de clientes**

```
aws kendra create-data-source \
 --name data-source-name \
 --index-id index-id \
 --role-arn arn:aws:iam::account-id:role/role-name \
 --type S3 \
 --configuration '{"S3Configuration":{"BucketName":"S3-bucket-name"}}' \
 --custom-document-enrichment-configuration '{"InlineConfigurations":[{"Target":{"TargetDocumentAttributeKey":"Customer_ID", "TargetDocumentAttributeValueDeletion": true}}]}'
```

------
#### [ Python ]

**Para configurar la manipulación básica de datos para eliminar números de identificación de clientes**

```
import boto3
from botocore.exceptions import ClientError
import pprint
import time

kendra = boto3.client("kendra")

print("Create a data source with customizations")

# Provide the name of the data source
name = "data-source-name"
# Provide the index ID for the data source
index_id = "index-id"
# Provide the IAM role ARN required for data sources
role_arn = "arn:aws:iam::${account-id}:role/${role-name}"
# Provide the data source connection information
data_source_type = "S3"
S3_bucket_name = "S3-bucket-name"
# Configure the data source with Custom Document Enrichment
configuration = {"S3Configuration":
        {
            "BucketName": S3_bucket_name
        }
    }
custom_document_enrichment_configuration = {"InlineConfigurations":[
        {
            "Target":{"TargetDocumentAttributeKey":"Customer_ID",
                       "TargetDocumentAttributeValueDeletion": True}
        }]
    }

try:
    data_source_response = kendra.create_data_source(
        Name = name,
        IndexId = index_id,
        RoleArn = role_arn,
        Type = data_source_type
        Configuration = configuration
        CustomDocumentEnrichmentConfiguration = custom_document_enrichment_configuration
    )

    pprint.pprint(data_source_response)

    data_source_id = data_source_response["Id"]

    print("Wait for Amazon Kendra to create the data source with your customizations.")

    while True:
        # Get the details of the data source, such as the status
        data_source_description = kendra.describe_data_source(
            Id = data_source_id,
            IndexId = index_id
        )
        status = data_source_description["Status"]
        print(" Creating data source. Status: "+status)
        time.sleep(60)
        if status != "CREATING":
            break

    print("Synchronize the data source.")

    sync_response = kendra.start_data_source_sync_job(
        Id = data_source_id,
        IndexId = index_id
    )

    pprint.pprint(sync_response)

    print("Wait for the data source to sync with the index.")

    while True:

        jobs = kendra.list_data_source_sync_jobs(
            Id= data_source_id,
            IndexId= index_id
        )

        # For this example, there should be one job
        status = jobs["History"][0]["Status"]

        print(" Syncing data source. Status: "+status)
        time.sleep(60)
        if status != "SYNCING":
            break

except  ClientError as e:
        print("%s" % e)

print("Program ends.")
```

------
#### [ Java ]

**Para configurar la manipulación básica de datos para eliminar números de identificación de clientes**

```
package com.amazonaws.kendra;

import java.util.concurrent.TimeUnit;
import software.amazon.awssdk.services.kendra.KendraClient;
import software.amazon.awssdk.services.kendra.model.CreateDataSourceRequest;
import software.amazon.awssdk.services.kendra.model.CreateDataSourceResponse;
import software.amazon.awssdk.services.kendra.model.CreateIndexRequest;
import software.amazon.awssdk.services.kendra.model.CreateIndexResponse;
import software.amazon.awssdk.services.kendra.model.DataSourceConfiguration;
import software.amazon.awssdk.services.kendra.model.DataSourceStatus;
import software.amazon.awssdk.services.kendra.model.DataSourceSyncJob;
import software.amazon.awssdk.services.kendra.model.DataSourceSyncJobStatus;
import software.amazon.awssdk.services.kendra.model.DataSourceType;
import software.amazon.awssdk.services.kendra.model.DescribeDataSourceRequest;
import software.amazon.awssdk.services.kendra.model.DescribeDataSourceResponse;
import software.amazon.awssdk.services.kendra.model.DescribeIndexRequest;
import software.amazon.awssdk.services.kendra.model.DescribeIndexResponse;
import software.amazon.awssdk.services.kendra.model.IndexStatus;
import software.amazon.awssdk.services.kendra.model.ListDataSourceSyncJobsRequest;
import software.amazon.awssdk.services.kendra.model.ListDataSourceSyncJobsResponse;
import software.amazon.awssdk.services.kendra.model.S3DataSourceConfiguration;
import software.amazon.awssdk.services.kendra.model.StartDataSourceSyncJobRequest;
import software.amazon.awssdk.services.kendra.model.StartDataSourceSyncJobResponse;

public class CreateDataSourceWithCustomizationsExample {

    public static void main(String[] args) throws InterruptedException {
        System.out.println("Create a data source with customizations");
        
        String dataSourceName = "data-source-name";
        String indexId = "index-id";
        String dataSourceRoleArn = "arn:aws:iam::account-id:role/role-name";
        String s3BucketName = "S3-bucket-name"

        KendraClient kendra = KendraClient.builder().build();
        
        CreateDataSourceRequest createDataSourceRequest = CreateDataSourceRequest
            .builder()
            .name(dataSourceName)
            .description(experienceDescription)
            .roleArn(experienceRoleArn)
            .type(DataSourceType.S3)
            .configuration(
                DataSourceConfiguration
                    .builder()
                    .s3Configuration(
                        S3DataSourceConfiguration
                            .builder()
                            .bucketName(s3BucketName)
                            .build()
                    ).build()
            )
            .customDocumentEnrichmentConfiguration(
                CustomDocumentEnrichmentConfiguration
                    .builder()
                    .inlineConfigurations(Arrays.asList(
                        InlineCustomDocumentEnrichmentConfiguration
                            .builder()
                            .target(
                                DocumentAttributeTarget
                                    .builder()
                                    .targetDocumentAttributeKey("Customer_ID")
                                    .targetDocumentAttributeValueDeletion(true)
                                    .build())
                            .build()
                    )).build();
        
        CreateDataSourceResponse createDataSourceResponse = kendra.createDataSource(createDataSourceRequest);
        System.out.println(String.format("Response of creating data source: %s", createDataSourceResponse));

        String dataSourceId = createDataSourceResponse.id();
        System.out.println(String.format("Waiting for Kendra to create the data source %s", dataSourceId));
        DescribeDataSourceRequest describeDataSourceRequest = DescribeDataSourceRequest
            .builder()
            .indexId(indexId)
            .id(dataSourceId)
            .build();

        while (true) {
            DescribeDataSourceResponse describeDataSourceResponse = kendra.describeDataSource(describeDataSourceRequest);

            DataSourceStatus status = describeDataSourceResponse.status();
            System.out.println(String.format("Creating data source. Status: %s", status));
            TimeUnit.SECONDS.sleep(60);
            if (status != DataSourceStatus.CREATING) {
                break;
            }
        }

        System.out.println(String.format("Synchronize the data source %s", dataSourceId));
        StartDataSourceSyncJobRequest startDataSourceSyncJobRequest = StartDataSourceSyncJobRequest
            .builder()
            .indexId(indexId)
            .id(dataSourceId)
            .build();
        StartDataSourceSyncJobResponse startDataSourceSyncJobResponse = kendra.startDataSourceSyncJob(startDataSourceSyncJobRequest);
        System.out.println(String.format("Waiting for the data source to sync with the index %s for execution ID %s", indexId, startDataSourceSyncJobResponse.executionId()));

        // For this example, there should be one job
        ListDataSourceSyncJobsRequest listDataSourceSyncJobsRequest = ListDataSourceSyncJobsRequest
            .builder()
            .indexId(indexId)
            .id(dataSourceId)
            .build();

        while (true) {
            ListDataSourceSyncJobsResponse listDataSourceSyncJobsResponse = kendra.listDataSourceSyncJobs(listDataSourceSyncJobsRequest);
            DataSourceSyncJob job = listDataSourceSyncJobsResponse.history().get(0);
            System.out.println(String.format("Syncing data source. Status: %s", job.status()));

            TimeUnit.SECONDS.sleep(60);
            if (job.status() != DataSourceSyncJobStatus.SYNCING) {
                break;
            }

        }

        System.out.println("Data source creation with customizations is complete");
    }
}
```

------

## Funciones de Lambda: extraer y cambiar metadatos o contenido
<a name="advanced-data-manipulation"></a>

Puede manipular los campos y el contenido de los documentos mediante las funciones de Lambda. Esto resulta útil si desea ir más allá de la lógica básica y aplicar manipulaciones avanzadas de datos. Por ejemplo, mediante el reconocimiento óptico de caracteres (OCR), que interpreta el texto de las imágenes y trata cada imagen como un documento textual. O bien, recuperar la fecha y hora actual en una zona horaria determinada e insertar la fecha y hora donde haya un valor vacío para un campo de fecha.

Puede aplicar primero la lógica básica y, a continuación, utilizar una función de Lambda para manipular aún más los datos o viceversa. También puede optar por aplicar solo una función de Lambda.

Amazon Kendra puede invocar una función Lambda para aplicar manipulaciones de datos avanzadas durante el proceso de ingesta como parte de su. [CustomDocumentEnrichmentConfiguration](https://docs.aws.amazon.com/kendra/latest/APIReference/API_CustomDocumentEnrichmentConfiguration.html) [Usted especifica un rol que incluye permiso para ejecutar la función Lambda y acceder a su Amazon S3 bucket para almacenar el resultado de sus manipulaciones IAM de datos (consulte roles de acceso).](https://docs.aws.amazon.com/kendra/latest/dg/iam-roles.html)

Amazon Kendra puede aplicar una función Lambda a los documentos originales sin procesar o a los documentos estructurados y analizados. Puede configurar una función Lambda que tome sus datos originales o sin procesar y aplique sus manipulaciones de datos mediante. [PreExtractionHookConfiguration](https://docs.aws.amazon.com/kendra/latest/APIReference/API_CustomDocumentEnrichmentConfiguration.html) También puede configurar una función Lambda que tome sus documentos estructurados y aplique sus manipulaciones de datos mediante. [PostExtractionHookConfiguration](https://docs.aws.amazon.com/kendra/latest/APIReference/API_CustomDocumentEnrichmentConfiguration.html) Amazon Kendra extrae los metadatos y el texto del documento para estructurarlos. Sus funciones Lambda deben seguir las estructuras obligatorias de solicitud y respuesta. Para obtener más información, consulte [Contratos de datos para funciones Lambda](#cde-data-contracts-lambda).

Para configurar una función Lambda en la consola, seleccione el índice y, a continuación, seleccione **Document enrichments**(Enriquecimiento de documentos) en el menú de navegación. Vaya a **Configurar funciones Lambda** para configurar una función Lambda.

Solo puede configurar una función Lambda para `PreExtractionHookConfiguration` y solo una función Lambda para `PostExtractionHookConfiguration`. Sin embargo, la función Lambda puede invocar otras funciones que requiere. Puede configurar ambos `PreExtractionHookConfiguration` y `PostExtractionHookConfiguration`, o cualquiera de los dos. La función Lambda para `PreExtractionHookConfiguration` no debe exceder un tiempo de ejecución de 5 minutos y su función Lambda para `PostExtractionHookConfiguration` no debe exceder un tiempo de ejecución de 1 minuto. Naturalmente, si se configura el enriquecimiento de documentos personalizado, se tarda más tiempo en procesar los documentos Amazon Kendra que si no se configurara.

Puede configurarlo Amazon Kendra para invocar una función Lambda solo si se cumple una condición. Por ejemplo, puede especificar una condición según la cual, si hay valores de fecha y hora vacíos, se invoque una función que Amazon Kendra inserte la fecha y hora actuales.

A continuación se muestra un ejemplo de uso de una función Lambda para ejecutar OCR para interpretar texto de imágenes y almacenar este texto en un campo denominado “Document\$1Image\$1Text”.

**Ejemplo 1: Extracción de texto de imágenes para crear documentos textuales**

Datos antes de aplicar la manipulación avanzada.


| **Document\$1ID** | **Document\$1Image** | 
| --- | --- | 
| 1 | image\$11.png | 
| 2 | image\$12.png | 
| 3 | image\$13.png | 

Datos después de aplicar la manipulación avanzada.


| **Document\$1ID** | **Document\$1Image** | **Document\$1Image\$1Text** | 
| --- | --- | --- | 
| 1 | image\$11.png | Mailed survey response | 
| 2 | image\$12.png | Mailed survey response | 
| 3 | image\$13.png | Mailed survey response | 

A continuación se muestra un ejemplo de uso de una función Lambda para insertar la fecha y hora actual para valores de fecha vacíos. Utiliza la condición de que si el valor de un campo de fecha es “null”, se sustituye por la fecha y hora actuales.

**Ejemplo 2: Sustitución de valores vacíos en el campo Last\$1Updated por la fecha y hora actuales.**

Datos antes de aplicar la manipulación avanzada.


| **Document\$1ID** | **Body\$1Text** | **Last\$1Updated** | 
| --- | --- | --- | 
| 1 | Lorem Ipsum. | 1 de enero de 2020 | 
| 2 | Lorem Ipsum. |   | 
| 3 | Lorem Ipsum. | July 1, 2020 | 

Datos después de aplicar la manipulación avanzada.


| **Document\$1ID** | **Body\$1Text** | **Last\$1Updated** | 
| --- | --- | --- | 
| 1 | Lorem Ipsum. | 1 de enero de 2020 | 
| 2 | Lorem Ipsum. | December 1, 2021 | 
| 3 | Lorem Ipsum. | July 1, 2020 | 

El siguiente código es un ejemplo de configuración de una función Lambda para la manipulación avanzada de datos en los datos originales y sin procesar.

------
#### [ Console ]

**Para configurar una función Lambda para la manipulación avanzada de datos en los datos originales sin procesar**

1. En el panel de navegación izquierdo, en **Indexes** (Índices), seleccione **Document enrichments** (Enriquecimiento de documentos) y luego seleccione **Add document enrichment** (Añadir enriquecimiento de documentos).

1. En la página **Configurar funciones de Lambda**, en la sección **Lambda para la extracción previa**, seleccione en los menús desplegables el ARN de la función de Lambda y su bucket. Amazon S3 Añada su rol de IAM acceso seleccionando la opción de crear un nuevo rol en el menú desplegable. Esto crea los Amazon Kendra permisos necesarios para crear el enriquecimiento de documentos.

------
#### [ CLI ]

**Para configurar una función Lambda para la manipulación avanzada de datos en los datos originales sin procesar**

```
aws kendra create-data-source \
 --name data-source-name \
 --index-id index-id \
 --role-arn arn:aws:iam::account-id:role/role-name \
 --type S3 \
 --configuration '{"S3Configuration":{"BucketName":"S3-bucket-name"}}' \
 --custom-document-enrichment-configuration '{"PreExtractionHookConfiguration":{"LambdaArn":"arn:aws:iam::account-id:function/function-name", "S3Bucket":"S3-bucket-name"}, "RoleArn": "arn:aws:iam:account-id:role/cde-role-name"}'
```

------
#### [ Python ]

**Para configurar una función Lambda para la manipulación avanzada de datos en los datos originales sin procesar**

```
import boto3
from botocore.exceptions import ClientError
import pprint
import time

kendra = boto3.client("kendra")

print("Create a data source with customizations.")

# Provide the name of the data source
name = "data-source-name"
# Provide the index ID for the data source
index_id = "index-id"
# Provide the IAM role ARN required for data sources
role_arn = "arn:aws:iam::${account-id}:role/${role-name}"
# Provide the data source connection information
data_source_type = "S3"
S3_bucket_name = "S3-bucket-name"
# Configure the data source with Custom Document Enrichment
configuration = {"S3Configuration":
        {
            "BucketName": S3_bucket_name
        }
    }
custom_document_enrichment_configuration = {"PreExtractionHookConfiguration":
        {
            "LambdaArn":"arn:aws:iam::account-id:function/function-name",
            "S3Bucket":"S3-bucket-name"
        }
    "RoleArn":"arn:aws:iam::account-id:role/cde-role-name"
    }

try:
    data_source_response = kendra.create_data_source(
        Name = name,
        IndexId = index_id,
        RoleArn = role_arn,
        Type = data_source_type
        Configuration = configuration
        CustomDocumentEnrichmentConfiguration = custom_document_enrichment_configuration
    )

    pprint.pprint(data_source_response)

    data_source_id = data_source_response["Id"]

    print("Wait for Amazon Kendra to create the data source with your customizations.")

    while True:
        # Get the details of the data source, such as the status
        data_source_description = kendra.describe_data_source(
            Id = data_source_id,
            IndexId = index_id
        )
        status = data_source_description["Status"]
        print(" Creating data source. Status: "+status)
        time.sleep(60)
        if status != "CREATING":
            break

    print("Synchronize the data source.")

    sync_response = kendra.start_data_source_sync_job(
        Id = data_source_id,
        IndexId = index_id
    )

    pprint.pprint(sync_response)

    print("Wait for the data source to sync with the index.")

    while True:

        jobs = kendra.list_data_source_sync_jobs(
            Id = data_source_id,
            IndexId = index_id
        )

        # For this example, there should be one job
        status = jobs["History"][0]["Status"]

        print(" Syncing data source. Status: "+status)
        time.sleep(60)
        if status != "SYNCING":
            break

except  ClientError as e:
        print("%s" % e)

print("Program ends.")
```

------
#### [ Java ]

**Para configurar una función Lambda para la manipulación avanzada de datos en los datos originales sin procesar**

```
package com.amazonaws.kendra;

import java.util.concurrent.TimeUnit;
import software.amazon.awssdk.services.kendra.KendraClient;
import software.amazon.awssdk.services.kendra.model.CreateDataSourceRequest;
import software.amazon.awssdk.services.kendra.model.CreateDataSourceResponse;
import software.amazon.awssdk.services.kendra.model.CreateIndexRequest;
import software.amazon.awssdk.services.kendra.model.CreateIndexResponse;
import software.amazon.awssdk.services.kendra.model.DataSourceConfiguration;
import software.amazon.awssdk.services.kendra.model.DataSourceStatus;
import software.amazon.awssdk.services.kendra.model.DataSourceSyncJob;
import software.amazon.awssdk.services.kendra.model.DataSourceSyncJobStatus;
import software.amazon.awssdk.services.kendra.model.DataSourceType;
import software.amazon.awssdk.services.kendra.model.DescribeDataSourceRequest;
import software.amazon.awssdk.services.kendra.model.DescribeDataSourceResponse;
import software.amazon.awssdk.services.kendra.model.DescribeIndexRequest;
import software.amazon.awssdk.services.kendra.model.DescribeIndexResponse;
import software.amazon.awssdk.services.kendra.model.IndexStatus;
import software.amazon.awssdk.services.kendra.model.ListDataSourceSyncJobsRequest;
import software.amazon.awssdk.services.kendra.model.ListDataSourceSyncJobsResponse;
import software.amazon.awssdk.services.kendra.model.S3DataSourceConfiguration;
import software.amazon.awssdk.services.kendra.model.StartDataSourceSyncJobRequest;
import software.amazon.awssdk.services.kendra.model.StartDataSourceSyncJobResponse;


public class CreateDataSourceWithCustomizationsExample {

    public static void main(String[] args) throws InterruptedException {
        System.out.println("Create a data source with customizations");
        
        String dataSourceName = "data-source-name";
        String indexId = "index-id";
        String dataSourceRoleArn = "arn:aws:iam::account-id:role/role-name";
        String s3BucketName = "S3-bucket-name"

        KendraClient kendra = KendraClient.builder().build();
        
        CreateDataSourceRequest createDataSourceRequest = CreateDataSourceRequest
            .builder()
            .name(dataSourceName)
            .description(experienceDescription)
            .roleArn(experienceRoleArn)
            .type(DataSourceType.S3)
            .configuration(
                DataSourceConfiguration
                    .builder()
                    .s3Configuration(
                        S3DataSourceConfiguration
                            .builder()
                            .bucketName(s3BucketName)
                            .build()
                    ).build()
            )
            .customDocumentEnrichmentConfiguration(
                CustomDocumentEnrichmentConfiguration
                    .builder()
                    .preExtractionHookConfiguration(
                        HookConfiguration
                            .builder()
                            .lambdaArn("arn:aws:iam::account-id:function/function-name")
                            .s3Bucket("S3-bucket-name")
                            .build())
                    .roleArn("arn:aws:iam::account-id:role/cde-role-name")
                    .build();
        
        CreateDataSourceResponse createDataSourceResponse = kendra.createDataSource(createDataSourceRequest);
        System.out.println(String.format("Response of creating data source: %s", createDataSourceResponse));

        String dataSourceId = createDataSourceResponse.id();
        System.out.println(String.format("Waiting for Kendra to create the data source %s", dataSourceId));
        DescribeDataSourceRequest describeDataSourceRequest = DescribeDataSourceRequest
            .builder()
            .indexId(indexId)
            .id(dataSourceId)
            .build();

        while (true) {
            DescribeDataSourceResponse describeDataSourceResponse = kendra.describeDataSource(describeDataSourceRequest);

            DataSourceStatus status = describeDataSourceResponse.status();
            System.out.println(String.format("Creating data source. Status: %s", status));
            TimeUnit.SECONDS.sleep(60);
            if (status != DataSourceStatus.CREATING) {
                break;
            }
        }

        System.out.println(String.format("Synchronize the data source %s", dataSourceId));
        StartDataSourceSyncJobRequest startDataSourceSyncJobRequest = StartDataSourceSyncJobRequest
            .builder()
            .indexId(indexId)
            .id(dataSourceId)
            .build();
        StartDataSourceSyncJobResponse startDataSourceSyncJobResponse = kendra.startDataSourceSyncJob(startDataSourceSyncJobRequest);
        System.out.println(String.format("Waiting for the data source to sync with the index %s for execution ID %s", indexId, startDataSourceSyncJobResponse.executionId()));

        // For this example, there should be one job
        ListDataSourceSyncJobsRequest listDataSourceSyncJobsRequest = ListDataSourceSyncJobsRequest
            .builder()
            .indexId(indexId)
            .id(dataSourceId)
            .build();

        while (true) {
            ListDataSourceSyncJobsResponse listDataSourceSyncJobsResponse = kendra.listDataSourceSyncJobs(listDataSourceSyncJobsRequest);
            DataSourceSyncJob job = listDataSourceSyncJobsResponse.history().get(0);
            System.out.println(String.format("Syncing data source. Status: %s", job.status()));

            TimeUnit.SECONDS.sleep(60);
            if (job.status() != DataSourceSyncJobStatus.SYNCING) {
                break;
            }

        }

        System.out.println("Data source creation with customizations is complete");
    }
}
```

------

## Contratos de datos para funciones Lambda
<a name="cde-data-contracts-lambda"></a>

Sus funciones Lambda para la manipulación avanzada de datos interactúan con contratos de datos de Amazon Kendra . Los contratos son las estructuras de solicitud y respuesta obligatorias de sus funciones Lambda. Si las funciones Lambda no siguen estas estructuras, se Amazon Kendra produce un error.

La función Lambda para `PreExtractionHookConfiguration` debería esperar la siguiente estructura de solicitud:

```
{
    "version": <str>,
    "dataBlobStringEncodedInBase64": <str>, //In the case of a data blob
    "s3Bucket": <str>, //In the case of an S3 bucket
    "s3ObjectKey": <str>, //In the case of an S3 bucket
    "metadata": <Metadata>
}
```

La estructura de `metadata`, que incluye la estructura de `CustomDocumentAttribute`, es la siguiente:

```
{
    "attributes": [<CustomDocumentAttribute<]
}

CustomDocumentAttribute
{
    "name": <str>,
    "value": <CustomDocumentAttributeValue>
}

CustomDocumentAttributeValue
{
    "stringValue": <str>,
    "integerValue": <int>,
    "longValue": <long>,
    "stringListValue": list<str>,
    "dateValue": <str>
}
```

La función Lambda para `PreExtractionHookConfiguration` debe cumplir la siguiente estructura de respuesta:

```
{
    "version": <str>,
    "dataBlobStringEncodedInBase64": <str>, //In the case of a data blob
    "s3ObjectKey": <str>, //In the case of an S3 bucket
    "metadataUpdates": [<CustomDocumentAttribute>]
}
```

La función Lambda para `PostExtractionHookConfiguration` debería esperar la siguiente estructura de solicitud:

```
{
    "version": <str>,
    "s3Bucket": <str>,
    "s3ObjectKey": <str>,
    "metadata": <Metadata>
}
```

La función Lambda para `PostExtractionHookConfiguration` debe cumplir la siguiente estructura de respuesta:

```
PostExtractionHookConfiguration Lambda Response
{
    "version": <str>,
    "s3ObjectKey": <str>,
    "metadataUpdates": [<CustomDocumentAttribute>]
}
```

El documento modificado se carga en el Amazon S3 bucket. El documento modificado debe seguir el formato que se muestra en [Formato del documento estructurado](#structured-document-format).

### Formato del documento estructurado
<a name="structured-document-format"></a>

Amazon Kendra carga el documento estructurado en el Amazon S3 depósito correspondiente. El documento estructurado sigue este formato:

```
Kendra document

{
   "textContent": <TextContent>
}

TextContent
{
  "documentBodyText": <str>
}
```

### Ejemplo de una función Lambda que se adhiere a los contratos de datos
<a name="example-lambda-function-advanced-manipulation"></a>

El siguiente código de Python es un ejemplo de una función Lambda que aplica manipulación avanzada de los campos de metadatos `_authors`, `_document_title` y el contenido del cuerpo de los documentos originales o sin procesar.

**En el caso del contenido corporal que reside en un depósito Amazon S3 **

```
import json
import boto3
     
s3 = boto3.client("s3")

# Lambda function for advanced data manipulation    
def lambda_handler(event, context):
    # Get the value of "S3Bucket" key name or item from the given event input
    s3_bucket = event.get("s3Bucket")
    # Get the value of "S3ObjectKey" key name or item from the given event input
    s3_object_key = event.get("s3ObjectKey")
    
    content_object_before_CDE = s3.get_object(Bucket = s3_bucket, Key = s3_object_key)
    content_before_CDE = content_object_before_CDE["Body"].read().decode("utf-8");
    content_after_CDE = "CDEInvolved " + content_before_CDE
    
    # Get the value of "metadata" key name or item from the given event input
    metadata = event.get("metadata")
    # Get the document "attributes" from the metadata 
    document_attributes = metadata.get("attributes")
    
    s3.put_object(Bucket = s3_bucket, Key = "dummy_updated_kendra_document", Body=json.dumps(content_after_CDE))
    return {
        "version": "v0",
        "s3ObjectKey": "dummy_updated_kendra_document",
        "metadataUpdates": [
            {"name":"_document_title", "value":{"stringValue":"title_from_pre_extraction_lambda"}},
            {"name":"_authors", "value":{"stringListValue":["author1", "author2"]}}
        ]
    }
```

**En el caso del contenido del cuerpo que reside en un blob de datos** 

```
import json
import boto3
import base64

# Lambda function for advanced data manipulation
def lambda_handler(event, context):
    
    # Get the value of "dataBlobStringEncodedInBase64" key name or item from the given event input 
    data_blob_string_encoded_in_base64 = event.get("dataBlobStringEncodedInBase64")
    # Decode the data blob string in UTF-8
    data_blob_string = base64.b64decode(data_blob_string_encoded_in_base64).decode("utf-8")
    # Get the value of "metadata" key name or item from the given event input    
    metadata = event.get("metadata")
    # Get the document "attributes" from the metadata
    document_attributes = metadata.get("attributes")
    
    new_data_blob = "This should be the modified data in the document by pre processing lambda ".encode("utf-8")
    return {
        "version": "v0",
        "dataBlobStringEncodedInBase64": base64.b64encode(new_data_blob).decode("utf-8"),
        "metadataUpdates": [
            {"name":"_document_title", "value":{"stringValue":"title_from_pre_extraction_lambda"}},
            {"name":"_authors", "value":{"stringListValue":["author1", "author2"]}}
        ]
    }
```

El siguiente código de Python es un ejemplo de una función Lambda que aplica manipulación avanzada de los campos de metadatos `_authors`, `_document_title` y el contenido del cuerpo de los documentos estructurados o analizados.

```
import json
import boto3
import time

s3 = boto3.client("s3")

# Lambda function for advanced data manipulation
def lambda_handler(event, context):
    
    # Get the value of "S3Bucket" key name or item from the given event input
    s3_bucket = event.get("s3Bucket")
    # Get the value of "S3ObjectKey" key name or item from the given event input
    s3_key = event.get("s3ObjectKey")
    # Get the value of "metadata" key name or item from the given event input
    metadata = event.get("metadata")
    # Get the document "attributes" from the metadata 
    document_attributes = metadata.get("attributes")
    
    kendra_document_object = s3.get_object(Bucket = s3_bucket, Key = s3_key)
    kendra_document_string = kendra_document_object['Body'].read().decode('utf-8')
    kendra_document = json.loads(kendra_document_string)
    kendra_document["textContent"]["documentBodyText"] = "Changing document body to a short sentence."
    
    s3.put_object(Bucket = s3_bucket, Key = "dummy_updated_kendra_document", Body=json.dumps(kendra_document))

    return {
        "version" : "v0",
        "s3ObjectKey": "dummy_updated_kendra_document",
        "metadataUpdates": [
            {"name": "_document_title", "value":{"stringValue": "title_from_post_extraction_lambda"}},
            {"name": "_authors", "value":{"stringListValue":["author1", "author2"]}}
        ]
    }
```