

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.

# Utiliser des indices secondaires
<a name="ddb-en-client-use-secindex"></a>

La [clé primaire](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean) d'une table définit l'index principal, qui détermine la manière dont DynamoDB stocke et extrait les éléments par défaut. 

Les index secondaires fournissent des clés alternatives que vous pouvez utiliser dans les opérations de requête et d'analyse. Les index secondaires globaux (GSI) possèdent une clé de partition et une clé de tri facultative qui peuvent être différentes de celles de la table de base. En revanche, les index secondaires locaux (LSI) partagent la clé de partition de l'index principal mais définissent une clé de tri différente.

## Définition des clés pour les index secondaires globaux et locaux
<a name="ddb-en-client-use-secindex-annomodel"></a>

Les attributs qui participent aux index secondaires nécessitent l'`@DynamoDbSecondarySortKey`annotation `@DynamoDbSecondaryPartitionKey` ou.

La classe suivante montre les annotations pour deux indices. Le GSI nommé *SubjectLastPostedDateIndex*utilise l'`Subject`attribut pour la clé de partition et `LastPostedDateTime` pour la clé de tri. Le LSI nommé *ForumLastPostedDateIndex*utilise le `ForumName` comme clé de partition et `LastPostedDateTime` comme clé de tri.

Notez que l'`Subject`attribut joue un double rôle. Il s'agit de la clé de tri de la clé primaire et de la clé de partition du GSI nommé *SubjectLastPostedDateIndex*.

### classe `MessageThread`
<a name="ddb-en-client-use-secindex-class"></a>

La `MessageThread` classe peut être utilisée comme classe de données pour l'[exemple de table de threads](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AppendixSampleTables.html) du manuel *Amazon DynamoDB Developer* Guide.

#### Importations
<a name="ddb-en-client-use-secindex-classimports"></a>

```
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondaryPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondarySortKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

import java.util.List;
```

```
@DynamoDbBean
public class MessageThread {
    private String ForumName;
    private String Subject;
    private String Message;
    private String LastPostedBy;
    private String LastPostedDateTime;
    private Integer Views;
    private Integer Replies;
    private Integer Answered;
    private List<String> Tags;

    @DynamoDbPartitionKey
    public String getForumName() {
        return ForumName;
    }

    public void setForumName(String forumName) {
        ForumName = forumName;
    }

    // Sort key for primary index and partition key for GSI "SubjectLastPostedDateIndex".
    @DynamoDbSortKey
    @DynamoDbSecondaryPartitionKey(indexNames = "SubjectLastPostedDateIndex")
    public String getSubject() {
        return Subject;
    }

    public void setSubject(String subject) {
        Subject = subject;
    }

    // Sort key for GSI "SubjectLastPostedDateIndex" and sort key for LSI "ForumLastPostedDateIndex".
    @DynamoDbSecondarySortKey(indexNames = {"SubjectLastPostedDateIndex", "ForumLastPostedDateIndex"})
    public String getLastPostedDateTime() {
        return LastPostedDateTime;
    }

    public void setLastPostedDateTime(String lastPostedDateTime) {
        LastPostedDateTime = lastPostedDateTime;
    }
    public String getMessage() {
        return Message;
    }

    public void setMessage(String message) {
        Message = message;
    }

    public String getLastPostedBy() {
        return LastPostedBy;
    }

    public void setLastPostedBy(String lastPostedBy) {
        LastPostedBy = lastPostedBy;
    }

    public Integer getViews() {
        return Views;
    }

    public void setViews(Integer views) {
        Views = views;
    }

    @DynamoDbSecondaryPartitionKey(indexNames = "ForumRepliesIndex")
    public Integer getReplies() {
        return Replies;
    }

    public void setReplies(Integer replies) {
        Replies = replies;
    }

    public Integer getAnswered() {
        return Answered;
    }

    public void setAnswered(Integer answered) {
        Answered = answered;
    }

    public List<String> getTags() {
        return Tags;
    }

    public void setTags(List<String> tags) {
        Tags = tags;
    }

    public MessageThread() {
        this.Answered = 0;
        this.LastPostedBy = "";
        this.ForumName = "";
        this.Message = "";
        this.LastPostedDateTime = "";
        this.Replies = 0;
        this.Views = 0;
        this.Subject = "";
    }

    @Override
    public String toString() {
        return "MessageThread{" +
                "ForumName='" + ForumName + '\'' +
                ", Subject='" + Subject + '\'' +
                ", Message='" + Message + '\'' +
                ", LastPostedBy='" + LastPostedBy + '\'' +
                ", LastPostedDateTime='" + LastPostedDateTime + '\'' +
                ", Views=" + Views +
                ", Replies=" + Replies +
                ", Answered=" + Answered +
                ", Tags=" + Tags +
                '}';
    }
}
```

## Création de l'index
<a name="ddb-en-client-use-secindex-confindex"></a>

À partir de la version 2.20.86 du SDK pour Java, la `createTable()` méthode génère automatiquement des index secondaires à partir des annotations de classes de données. Par défaut, tous les attributs de la table de base sont copiés dans un index et les valeurs de débit allouées sont de 20 unités de capacité de lecture et 20 unités de capacité d'écriture.

Toutefois, si vous utilisez une version du SDK antérieure à la version 2.20.86, vous devez créer l'index avec le tableau, comme indiqué dans l'exemple suivant. Cet exemple crée les deux index de la `Thread` table. Le paramètre [builder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/CreateTableEnhancedRequest.Builder.html) possède des méthodes pour configurer les deux types d'index, comme indiqué après les lignes de commentaire 1 et 2. Vous utilisez la `indexName()` méthode du générateur d'index pour associer les noms d'index spécifiés dans les annotations de classe de données au type d'index souhaité.

Ce code configure tous les attributs de table pour qu'ils apparaissent dans les deux index après les lignes de commentaires 3 et 4. De plus amples informations sur [les projections d'attributs](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LSI.html#LSI.Projections) sont disponibles dans le manuel du *développeur Amazon DynamoDB*.

```
    public static void createMessageThreadTable(DynamoDbTable<MessageThread> messageThreadDynamoDbTable, DynamoDbClient dynamoDbClient) {
        messageThreadDynamoDbTable.createTable(b -> b
                // 1. Generate the GSI.
                .globalSecondaryIndices(gsi -> gsi.indexName("SubjectLastPostedDateIndex")
                        // 3. Populate the GSI with all attributes.
                        .projection(p -> p
                                .projectionType(ProjectionType.ALL))
                )
                // 2. Generate the LSI.
                .localSecondaryIndices(lsi -> lsi.indexName("ForumLastPostedDateIndex")
                        // 4. Populate the LSI with all attributes.
                        .projection(p -> p
                                .projectionType(ProjectionType.ALL))
                )
        );
```

## Requête à l'aide d'un index
<a name="ddb-en-client-use-secindex-query"></a>

L’exemple suivant interroge l’index secondaire global *ForumLastPostedDateIndex*.

Après la ligne de commentaire 2, vous créez un [QueryConditional](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/QueryConditional.html)objet obligatoire lors de l'appel de la méthode [DynamoDbIndex.query()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbIndex.html#query(java.util.function.Consumer)). 

Vous obtenez une référence à l'index que vous souhaitez interroger après la ligne de commentaire 3 en transmettant le nom de l'index. Après la ligne de commentaire 4, vous appelez la `query()` méthode sur l'index qui transmet l'`QueryConditional`objet. 

Vous configurez également la requête pour renvoyer trois valeurs d'attribut, comme indiqué après la ligne de commentaire 5. Si elle n'`attributesToProject()`est pas appelée, la requête renvoie toutes les valeurs d'attribut. Notez que les noms d'attributs spécifiés commencent par des lettres minuscules. Ces noms d'attributs correspondent à ceux utilisés dans la table, pas nécessairement aux noms d'attributs de la classe de données.

Après la ligne de commentaire 6, parcourez les résultats, enregistrez chaque élément renvoyé par la requête et stockez-le également dans la liste pour le renvoyer à l'appelant.

```
public class IndexScanExamples {
    private static Logger logger = LoggerFactory.getLogger(IndexScanExamples.class);

    public static List<MessageThread> queryUsingSecondaryIndices(String lastPostedDate,
                                                                 DynamoDbTable<MessageThread> threadTable) {
        // 1. Log the parameter value.
        logger.info("lastPostedDate value: {}", lastPostedDate);

        // 2. Create a QueryConditional whose sort key value must be greater than or equal to the parameter value.
        QueryConditional queryConditional = QueryConditional.sortGreaterThanOrEqualTo(qc ->
                qc.partitionValue("Forum02").sortValue(lastPostedDate));

        // 3. Specify the index name to query.
        final DynamoDbIndex<MessageThread> forumLastPostedDateIndex = threadTable.index("ForumLastPostedDateIndex");

        // 4. Perform the query using the QueryConditional object.
        final SdkIterable<Page<MessageThread>> pagedResult = forumLastPostedDateIndex.query(q -> q
                .queryConditional(queryConditional)
                // 5. Request three attribute in the results.
                .attributesToProject("forumName", "subject", "lastPostedDateTime"));

        List<MessageThread> collectedItems = new ArrayList<>();
        // 6. Iterate through pages response and sort the items.
        pagedResult.stream().forEach(page -> page.items().stream()
                .sorted(Comparator.comparing(MessageThread::getLastPostedDateTime))
                .forEach(mt -> {
                    // 7. Log the returned items and add the collection to return to the caller.
                    logger.info(mt.toString());
                    collectedItems.add(mt);
                }));
        return collectedItems;
    }
```

Les éléments suivants existent dans la base de données avant l'exécution de la requête.

```
MessageThread{ForumName='Forum01', Subject='Subject01', Message='Message01', LastPostedBy='', LastPostedDateTime='2023.03.28', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum02', Subject='Subject02', Message='Message02', LastPostedBy='', LastPostedDateTime='2023.03.29', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum02', Subject='Subject04', Message='Message04', LastPostedBy='', LastPostedDateTime='2023.03.31', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum02', Subject='Subject08', Message='Message08', LastPostedBy='', LastPostedDateTime='2023.04.04', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum02', Subject='Subject10', Message='Message10', LastPostedBy='', LastPostedDateTime='2023.04.06', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum03', Subject='Subject03', Message='Message03', LastPostedBy='', LastPostedDateTime='2023.03.30', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum03', Subject='Subject06', Message='Message06', LastPostedBy='', LastPostedDateTime='2023.04.02', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum03', Subject='Subject09', Message='Message09', LastPostedBy='', LastPostedDateTime='2023.04.05', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum05', Subject='Subject05', Message='Message05', LastPostedBy='', LastPostedDateTime='2023.04.01', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum07', Subject='Subject07', Message='Message07', LastPostedBy='', LastPostedDateTime='2023.04.03', Views=0, Replies=0, Answered=0, Tags=null}
```

Les instructions de journalisation des lignes 1 et 6 génèrent la sortie de console suivante.

```
lastPostedDate value: 2023.03.31
MessageThread{ForumName='Forum02', Subject='Subject04', Message='', LastPostedBy='', LastPostedDateTime='2023.03.31', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum02', Subject='Subject08', Message='', LastPostedBy='', LastPostedDateTime='2023.04.04', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum02', Subject='Subject10', Message='', LastPostedBy='', LastPostedDateTime='2023.04.06', Views=0, Replies=0, Answered=0, Tags=null}
```

La requête a renvoyé des éléments avec une `forumName` valeur de *Forum02* et une `lastPostedDateTime` valeur supérieure ou égale à *2023.03.31*. Les résultats affichent `message` des valeurs avec une chaîne vide, bien que les `message` attributs contiennent des valeurs dans l'index. Cela est dû au fait que l'attribut message n'a pas été projeté par le code après la ligne de commentaire 5. 

## Utiliser des clés composites pour les index secondaires globaux (GSI)
<a name="ddb-en-client-use-secindex-composite"></a>

Le SDK pour Java 2.x DynamoDB Enhanced Client prend en charge les clés composites pour les index secondaires globaux. Vous pouvez définir jusqu'à quatre attributs de clé de partition et quatre attributs de clé de tri pour un seul GSI. Cela élimine le besoin de concaténer plusieurs attributs en une seule clé de chaîne côté client.

Utilisez le `order` paramètre sur les `@DynamoDbSecondarySortKey` annotations `@DynamoDbSecondaryPartitionKey` et pour spécifier la position de chaque attribut dans la clé composite. Le `order` paramètre accepte les valeurs de l'[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/Order.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/Order.html)énumération (intégrée au client DynamoDB amélioré) `FIRST` :`SECOND`,, et. `THIRD` `FOURTH`

### Annotez une classe de données avec des annotations clés composites
<a name="ddb-en-client-use-secindex-composite-anno"></a>

L'exemple suivant modélise une table de commandes. La table de base est utilisée `orderId` comme clé de partition. Un GSI nommé *OrdersByStatusDateAmount*utilise une clé de partition composite de `customerId` et`status`, et une clé de tri composite de `orderDate` et`amount`. Cette conception vous permet d'interroger les commandes d'un client filtrées par statut, date et seuil de montant.

#### Importations
<a name="ddb-en-client-use-secindex-composite-annoimports"></a>

```
import software.amazon.awssdk.enhanced.dynamodb.mapper.Order;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondaryPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondarySortKey;
```

```
@DynamoDbBean
public class OrderItem {
    private String orderId;
    private String customerId;
    private String status;
    private String orderDate;
    private Integer amount;

    @DynamoDbPartitionKey
    public String getOrderId() {
        return orderId;
    }
    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    // First partition key attribute for the GSI.
    @DynamoDbSecondaryPartitionKey(indexNames = "OrdersByStatusDateAmount", order = Order.FIRST)
    public String getCustomerId() {
        return customerId;
    }
    public void setCustomerId(String customerId) {
        this.customerId = customerId;
    }

    // Second partition key attribute for the GSI.
    @DynamoDbSecondaryPartitionKey(indexNames = "OrdersByStatusDateAmount", order = Order.SECOND)
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }

    // First sort key attribute for the GSI.
    @DynamoDbSecondarySortKey(indexNames = "OrdersByStatusDateAmount", order = Order.FIRST)
    public String getOrderDate() {
        return orderDate;
    }
    public void setOrderDate(String orderDate) {
        this.orderDate = orderDate;
    }

    // Second sort key attribute for the GSI.
    @DynamoDbSecondarySortKey(indexNames = "OrdersByStatusDateAmount", order = Order.SECOND)
    public Integer getAmount() {
        return amount;
    }
    public void setAmount(Integer amount) {
        this.amount = amount;
    }
}
```

### Requête à l'aide d'un index de clé composite
<a name="ddb-en-client-use-secindex-composite-query"></a>

Lorsque vous interrogez un index de clé composite, utilisez les `addSortValue()` méthodes `addPartitionValue()` et du générateur de [clés](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/Key.html). Ajoutez des valeurs dans le même ordre que les `Order` valeurs définies dans les annotations. Toutes les clés de partition sont requises. Les touches de tri sont facultatives et peuvent être fournies de gauche à droite.

Vous créez un [QueryConditional](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/QueryConditional.html)objet pour spécifier la condition de la requête. `keyEqualTo`À utiliser pour des correspondances exactes ou pour une condition clé de tri telle que `sortGreaterThan``sortLessThan`,`sortBetween`, ou`sortBeginsWith`. La condition s'applique à la dernière clé de tri que vous fournissez.

Les exemples suivants interrogent le *OrdersByStatusDateAmount*GSI, en ajoutant progressivement des clés de tri pour affiner les résultats.

```
DynamoDbIndex<OrderItem> index = orderTable.index("OrdersByStatusDateAmount");

// All PENDING orders for customer-123.
SdkIterable<Page<OrderItem>> allPending = index.query(q -> q
        .queryConditional(QueryConditional.keyEqualTo(k -> k
                .addPartitionValue("customer-123")
                .addPartitionValue("PENDING"))));

// PENDING orders on a specific date.
SdkIterable<Page<OrderItem>> pendingOnDate = index.query(q -> q
        .queryConditional(QueryConditional.keyEqualTo(k -> k
                .addPartitionValue("customer-123")
                .addPartitionValue("PENDING")
                .addSortValue("2025-11-04"))));

// PENDING orders on a specific date with amount greater than 100.
SdkIterable<Page<OrderItem>> filtered = index.query(q -> q
        .queryConditional(QueryConditional.sortGreaterThan(k -> k
                .addPartitionValue("customer-123")
                .addPartitionValue("PENDING")
                .addSortValue("2025-11-04")
                .addSortValue(100))));
```

Pour plus d'informations, consultez la section [Multi-key prise en charge de l'index secondaire global dans DynamoDB](https://aws.amazon.com/blogs/database/multi-key-support-for-global-secondary-index-in-amazon-dynamodb/).