

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Enrichir vos documents lors de l'ingestion
<a name="custom-document-enrichment"></a>

**Note**  
La prise en charge des fonctionnalités varie en fonction du type d'index et de l'API de recherche utilisés. Pour savoir si cette fonctionnalité est prise en charge pour le type d'index et l'API de recherche que vous utilisez, consultez la section [Types d'index](https://docs.aws.amazon.com/kendra/latest/dg/hiw-index-types.html).

Vous pouvez modifier le contenu et les champs ou attributs des métadonnées du document pendant le processus d'ingestion du document. Grâce à Amazon Kendra la fonction *d'enrichissement personnalisé des documents*, vous pouvez créer, modifier ou supprimer les attributs et le contenu des documents lorsque vous les ingérez. Amazon Kendra Cela signifie que vous pouvez manipuler et ingérer vos données selon vos besoins.

Cette fonctionnalité vous permet de contrôler la manière dont vos documents sont traités et ingérés. Amazon Kendra Par exemple, vous pouvez supprimer les informations personnellement identifiables contenues dans les métadonnées du document lors de l'ingestion de vos documents. Amazon Kendra

Vous pouvez également utiliser cette fonctionnalité en invoquant une fonction Lambda AWS Lambda pour exécuter la reconnaissance optique de caractères (OCR) sur des images, une traduction sur du texte et d'autres tâches de préparation des données pour la recherche ou l'analyse. Par exemple, vous pouvez appeler une fonction pour exécuter l'OCR sur des images. La fonction pouvait interpréter le texte des images et traiter chaque image comme un document textuel. Une entreprise qui reçoit des enquêtes clients envoyées par la poste et qui les stocke sous forme d'images pourrait intégrer ces images sous forme de documents textuels. Amazon Kendra L'entreprise peut ensuite rechercher des informations précieuses issues de sondages auprès des clients dans Amazon Kendra.

Vous pouvez utiliser des opérations de base à appliquer lors de la première analyse de vos données, puis utiliser une fonction Lambda pour appliquer des opérations plus complexes à vos données. Par exemple, vous pouvez utiliser une opération de base pour simplement supprimer toutes les valeurs du champ de métadonnées du document « Customer\$1ID », puis appliquer une fonction Lambda pour extraire le texte des images du texte des documents.

## Comment fonctionne l'enrichissement personnalisé des documents
<a name="how-custom-document-enrichment-works"></a>

Le processus global d'enrichissement de documents personnalisés est le suivant :

1. Vous configurez l'enrichissement personnalisé des documents lorsque vous créez ou mettez à jour votre source de données, ou lorsque vous y indexez directement vos documents Amazon Kendra.

1. Amazon Kendra applique des configurations intégrées ou une logique de base pour modifier vos données. Pour de plus amples informations, veuillez consulter [Opérations de base pour modifier les métadonnées](#basic-data-maniplation).

1. Si vous choisissez de configurer la manipulation avancée des données, vous Amazon Kendra pouvez l'appliquer à vos documents bruts originaux ou aux documents structurés et analysés. Pour de plus amples informations, veuillez consulter [Fonctions Lambda : extraire et modifier les métadonnées ou le contenu](#advanced-data-manipulation).

1. Vos documents modifiés sont ingérés dans. Amazon Kendra

À tout moment de ce processus, si votre configuration n'est pas valide, une Amazon Kendra erreur est générée.

Lorsque vous appelez [CreateDataSource](https://docs.aws.amazon.com/kendra/latest/APIReference/API_CreateDataSource.html), ou [UpdateDataSource[BatchPutDocument](https://docs.aws.amazon.com/kendra/latest/APIReference/API_BatchPutDocument.html)](https://docs.aws.amazon.com/kendra/latest/APIReference/API_UpdateDataSource.html) APIs, vous fournissez votre configuration personnalisée d'enrichissement de documents. Si vous appelez`BatchPutDocument`, vous devez configurer l'enrichissement personnalisé des documents à chaque demande. Si vous utilisez la console, vous sélectionnez votre index, puis sélectionnez **Enrichissements de documents** pour configurer l'enrichissement de documents personnalisé.

Si vous utilisez **les enrichissements de documents** dans la console, vous pouvez choisir de configurer uniquement les opérations de base ou uniquement les fonctions Lambda, ou les deux, comme vous pouvez le faire avec l'API. Vous pouvez sélectionner **Suivant** dans les étapes de la console pour choisir de ne pas configurer les opérations de base et uniquement les fonctions Lambda, notamment si elles doivent s'appliquer aux données d'origine (pré-extraction) ou structurées (après extraction). Vous ne pouvez enregistrer vos configurations qu'en effectuant toutes les étapes dans la console. Les configurations de vos documents ne sont pas enregistrées si vous n'effectuez pas toutes les étapes.

## Opérations de base pour modifier les métadonnées
<a name="basic-data-maniplation"></a>

Vous pouvez manipuler les champs et le contenu de votre document en utilisant une logique de base. Cela inclut la suppression de valeurs dans un champ, la modification des valeurs d'un champ à l'aide d'une condition ou la création d'un champ. Pour les manipulations avancées qui vont au-delà de ce que vous pouvez manipuler en utilisant la logique de base, appelez une fonction Lambda. Pour de plus amples informations, veuillez consulter [Fonctions Lambda : extraire et modifier les métadonnées ou le contenu](#advanced-data-manipulation).

Pour appliquer la logique de base, vous devez spécifier le champ cible que vous souhaitez manipuler à l'aide de l'[DocumentAttributeTarget](https://docs.aws.amazon.com/kendra/latest/APIReference/API_DocumentAttributeTarget.html)objet. Vous fournissez la clé d'attribut. Par exemple, la clé « Département » est un champ ou un attribut qui contient tous les noms de départements associés aux documents. Vous pouvez également spécifier une valeur à utiliser dans le champ cible si une certaine condition est remplie. Vous définissez la condition à l'aide de l'[DocumentAttributeCondition](https://docs.aws.amazon.com/kendra/latest/APIReference/API_DocumentAttributeCondition.html)objet. Par exemple, si le champ « Source\$1URI » contient « financier » dans sa valeur d'URI, préremplissez le champ cible « Department » avec la valeur cible « Finance » pour le document. Vous pouvez également supprimer les valeurs de l'attribut du document cible.

Pour appliquer une logique de base à l'aide de la console, sélectionnez votre index, puis sélectionnez **Enrichissements de documents** dans le menu de navigation. Accédez à **Configurer les opérations de base** pour appliquer des manipulations de base aux champs et au contenu de votre document.

Voici un exemple d'utilisation de la logique de base pour supprimer tous les numéros d'identification des clients dans le champ du document appelé « Customer\$1ID ».

**Exemple 1 : Supprimer les numéros d’identification des clients associés aux documents**

Données avant l'application de la manipulation de base.


| **Identifiant du document** | **Corps\$1Text** | **Identifiant\$1client** | 
| --- | --- | --- | 
| 1 | Lorem Ipsum. | CID1234 | 
| 2 | Lorem Ipsum. | CID1235 | 
| 3 | Lorem Ipsum. | CID1236 | 

Données appliquées après manipulation de base.


| **Identifiant du document** | **Corps\$1Text** | **Identifiant\$1client** | 
| --- | --- | --- | 
| 1 | Lorem Ipsum. |   | 
| 2 | Lorem Ipsum. |   | 
| 3 | Lorem Ipsum. |   | 

Voici un exemple d'utilisation de la logique de base pour créer un champ appelé « Department » et préremplir ce champ avec les noms des départements en fonction des informations du champ « Source\$1URI ». Cela utilise la condition selon laquelle si le champ « Source\$1URI » contient « financier » dans sa valeur d'URI, le champ cible « Department » est prérempli avec la valeur cible « Finance » pour le document.

**Exemple 2 : créer le champ « Département » et le préremplir avec les noms des départements associés aux documents à l'aide d'une condition.**

Données avant l'application de la manipulation de base.


| **Identifiant du document** | **Corps\$1Text** | **URI de la source** | 
| --- | --- | --- | 
| 1 | Lorem Ipsum. | financial/1 | 
| 2 | Lorem Ipsum. | financial/2 | 
| 3 | Lorem Ipsum. | financial/3 | 

Données appliquées après manipulation de base.


| **Identifiant du document** | **Corps\$1Text** | **URI de la source** | **Département** | 
| --- | --- | --- | --- | 
| 1 | Lorem Ipsum. | financial/1 | Finance | 
| 2 | Lorem Ipsum. | financial/2 | Finance | 
| 3 | Lorem Ipsum. | financial/3 | Finance | 

**Note**  
Amazon Kendra Impossible de créer un champ de document cible s'il n'est pas déjà créé en tant que champ d'index. Après avoir créé votre champ d'index, vous pouvez créer un champ de document à l'aide de`DocumentAttributeTarget`. Amazon Kendra fait ensuite correspondre le champ de métadonnées du document que vous venez de créer à votre champ d'index.

Le code suivant est un exemple de configuration de la manipulation de base des données pour supprimer les numéros d'identification des clients associés aux documents.

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

**Pour configurer la manipulation de base des données afin de supprimer les numéros d’identification des clients**

1. Dans le volet de navigation de gauche, sous **Index**, sélectionnez **Enrichissements de documents, puis sélectionnez Ajouter un enrichissement** **de document**.

1. Sur la page **Configurer les opérations de base**, choisissez dans le menu déroulant la source de données dont vous souhaitez modifier les champs et le contenu du document. **Choisissez ensuite dans le menu déroulant le nom du champ du document « Customer\$1ID », sélectionnez dans le menu déroulant le nom du champ d'index « Customer\$1ID » et sélectionnez dans le menu déroulant l'action cible Supprimer.** Sélectionnez ensuite **Ajouter une opération de base**.

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

**Pour configurer la manipulation de base des données afin de supprimer les numéros d’identification des clients**

```
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 ]

**Pour configurer la manipulation de base des données afin de supprimer les numéros d’identification des clients**

```
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 ]

**Pour configurer la manipulation de base des données afin de supprimer les numéros d’identification des clients**

```
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");
    }
}
```

------

## Fonctions Lambda : extraire et modifier les métadonnées ou le contenu
<a name="advanced-data-manipulation"></a>

Vous pouvez manipuler les champs et le contenu de votre document à l'aide des fonctions Lambda. Cela est utile si vous souhaitez aller au-delà de la logique de base et appliquer des manipulations de données avancées. Par exemple, utiliser la reconnaissance optique de caractères (OCR), qui interprète le texte des images et traite chaque image comme un document textuel. Vous pouvez également récupérer la date-heure actuelle dans un certain fuseau horaire et insérer la date-heure là où il y a une valeur vide pour un champ de date.

Vous pouvez d'abord appliquer une logique de base, puis utiliser une fonction Lambda pour continuer à manipuler vos données, ou vice versa. Vous pouvez également choisir de n'appliquer qu'une fonction Lambda.

Amazon Kendra peut invoquer une fonction Lambda pour appliquer des manipulations de données avancées pendant le processus d'ingestion dans le cadre de votre. [CustomDocumentEnrichmentConfiguration](https://docs.aws.amazon.com/kendra/latest/APIReference/API_CustomDocumentEnrichmentConfiguration.html) [Vous spécifiez un rôle qui inclut l'autorisation d'exécuter la fonction Lambda et d'accéder à votre Amazon S3 bucket pour stocker le résultat de vos manipulations IAM de données (voir rôles d'accès).](https://docs.aws.amazon.com/kendra/latest/dg/iam-roles.html)

Amazon Kendra peut appliquer une fonction Lambda sur vos documents bruts originaux ou sur les documents structurés et analysés. Vous pouvez configurer une fonction Lambda qui prend vos données d'origine ou brutes et applique vos manipulations de données à l'aide de. [PreExtractionHookConfiguration](https://docs.aws.amazon.com/kendra/latest/APIReference/API_CustomDocumentEnrichmentConfiguration.html) Vous pouvez également configurer une fonction Lambda qui prend vos documents structurés et applique vos manipulations de données à l'aide de. [PostExtractionHookConfiguration](https://docs.aws.amazon.com/kendra/latest/APIReference/API_CustomDocumentEnrichmentConfiguration.html) Amazon Kendra extrait les métadonnées et le texte du document pour structurer vos documents. Vos fonctions Lambda doivent respecter les structures de demande et de réponse obligatoires. Pour de plus amples informations, veuillez consulter [Contrats de données pour les fonctions Lambda](#cde-data-contracts-lambda).

Pour configurer une fonction Lambda dans la console, sélectionnez votre index, puis sélectionnez **Enrichissements de documents** dans le menu de navigation. Accédez à **Configurer les fonctions Lambda pour configurer une fonction** Lambda.

Vous ne pouvez configurer qu'une seule fonction Lambda pour `PreExtractionHookConfiguration` et une seule fonction Lambda pour. `PostExtractionHookConfiguration` Toutefois, votre fonction Lambda peut invoquer d'autres fonctions dont elle a besoin. Vous pouvez configurer `PreExtractionHookConfiguration` et `PostExtractionHookConfiguration` ou l’un des deux. Votre fonction Lambda pour ne `PreExtractionHookConfiguration` doit pas dépasser une durée d'exécution de 5 minutes et votre fonction Lambda pour ne `PostExtractionHookConfiguration` doit pas dépasser une durée d'exécution de 1 minute. La configuration de l'enrichissement personnalisé des documents prend naturellement plus de temps pour intégrer vos documents Amazon Kendra que si vous ne le configuriez pas.

Vous pouvez configurer Amazon Kendra pour appeler une fonction Lambda uniquement si une condition est remplie. Par exemple, vous pouvez spécifier une condition selon laquelle, s'il existe des valeurs date-heure vides, invoque une fonction qui insère la date-heure actuelle. Amazon Kendra 

Voici un exemple d'utilisation d'une fonction Lambda pour exécuter l'OCR afin d'interpréter du texte à partir d'images et de stocker ce texte dans un champ appelé « Document\$1Image\$1Text ».

**Exemple 1 : extraction de texte à partir d’images pour créer des documents textuels**

Données avant l'application de la manipulation avancée.


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

Les données ont été appliquées après manipulation avancée.


| **Identifiant du document** | **Document\$1Image** | **Document\$1Image\$1Texte** | 
| --- | --- | --- | 
| 1 | image\$11.png | Réponse au sondage envoyé | 
| 2 | image\$12.png | Réponse au sondage envoyé | 
| 3 | image\$13.png | Réponse au sondage envoyé | 

Voici un exemple d'utilisation d'une fonction Lambda pour insérer la date-heure actuelle pour les valeurs de date vides. Cela utilise la condition selon laquelle si la valeur d'un champ de date est « nulle », remplacez-la par la date-heure actuelle.

**Exemple 2 : remplacement des valeurs vides du champ Last\$1Updated par la date-heure actuelle.**

Données avant l'application de la manipulation avancée.


| **Identifiant du document** | **Corps\$1Text** | **Dernière mise à jour** | 
| --- | --- | --- | 
| 1 | Lorem Ipsum. | 1er janvier 2020 | 
| 2 | Lorem Ipsum. |   | 
| 3 | Lorem Ipsum. | 1er juillet 2020 | 

Les données ont été appliquées après manipulation avancée.


| **Identifiant du document** | **Corps\$1Text** | **Dernière mise à jour** | 
| --- | --- | --- | 
| 1 | Lorem Ipsum. | 1er janvier 2020 | 
| 2 | Lorem Ipsum. | 1er décembre 2021 | 
| 3 | Lorem Ipsum. | 1er juillet 2020 | 

Le code suivant est un exemple de configuration d'une fonction Lambda pour la manipulation avancée des données d'origine brutes.

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

**Pour configurer une fonction Lambda pour une manipulation avancée des données d'origine brutes**

1. Dans le volet de navigation de gauche, sous **Index**, sélectionnez **Enrichissements de documents, puis sélectionnez Ajouter un enrichissement** **de document**.

1. Sur la page **Configurer les fonctions Lambda**, dans la section **Lambda pour la pré-extraction**, sélectionnez dans les listes déroulantes l'ARN de votre fonction Lambda et votre bucket. Amazon S3 Ajoutez votre rôle IAM d'accès en sélectionnant l'option permettant de créer un nouveau rôle dans le menu déroulant. Cela crée les Amazon Kendra autorisations requises pour créer l'enrichissement du document.

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

**Pour configurer une fonction Lambda pour une manipulation avancée des données d'origine brutes**

```
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 ]

**Pour configurer une fonction Lambda pour une manipulation avancée des données d'origine brutes**

```
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 ]

**Pour configurer une fonction Lambda pour une manipulation avancée des données d'origine brutes**

```
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");
    }
}
```

------

## Contrats de données pour les fonctions Lambda
<a name="cde-data-contracts-lambda"></a>

Vos fonctions Lambda pour la manipulation avancée des données interagissent avec les contrats de Amazon Kendra données. Les contrats sont les structures de demande et de réponse obligatoires de vos fonctions Lambda. Si vos fonctions Lambda ne suivent pas ces structures, une erreur est Amazon Kendra générée.

Votre fonction Lambda pour `PreExtractionHookConfiguration` devrait s’attendre à la structure de requête suivante :

```
{
    "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 structure `metadata`, qui inclut la structure `CustomDocumentAttribute`, est la suivante :

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

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

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

Votre fonction Lambda pour `PreExtractionHookConfiguration` doit respecter la structure de réponse suivante :

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

Votre fonction Lambda pour `PostExtractionHookConfiguration` devrait s’attendre à la structure de requête suivante :

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

Votre fonction Lambda pour `PostExtractionHookConfiguration` doit respecter la structure de réponse suivante :

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

Votre document modifié est chargé dans votre Amazon S3 compartiment. Le document modifié doit suivre le format indiqué dans[Format de document structuré](#structured-document-format).

### Format de document structuré
<a name="structured-document-format"></a>

Amazon Kendra télécharge votre document structuré dans le Amazon S3 compartiment indiqué. Le document structuré suit le format suivant :

```
Kendra document

{
   "textContent": <TextContent>
}

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

### Exemple de fonction Lambda qui respecte les contrats de données
<a name="example-lambda-function-advanced-manipulation"></a>

Le code Python suivant est un exemple de fonction Lambda qui applique une manipulation avancée des champs `_authors` de métadonnées et du contenu du corps des documents bruts ou originaux. `_document_title`

**Dans le cas où le contenu corporel se trouve dans un Amazon S3 compartiment**

```
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"]}}
        ]
    }
```

**Dans le cas où le contenu du corps réside dans un blob de données**

```
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"]}}
        ]
    }
```

Le code Python suivant est un exemple de fonction Lambda qui applique une manipulation avancée des champs `_authors` de métadonnées et du contenu du corps des documents structurés ou analysés. `_document_title`

```
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"]}}
        ]
    }
```