

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.

# Utilisation d'index secondaires globaux : .NET
<a name="GSILowLevelDotNet"></a>

Vous pouvez utiliser l'API de AWS SDK pour .NET bas niveau pour créer une table Amazon DynamoDB avec un ou plusieurs index secondaires globaux, décrire les index de la table et effectuer des requêtes à l'aide des index. Ces opérations mappent aux opérations DynamoDB correspondantes. Pour plus d'informations, consultez la [Référence d'API Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/). 

Voici les étapes courantes pour les opérations de table à l'aide de l'API de bas niveau .NET. 

1. Créez une instance de la classe `AmazonDynamoDBClient`.

1. Fournissez les paramètres obligatoires et facultatifs pour l'opération en créant les objets de requête correspondants.

   Par exemple, créez un objet `CreateTableRequest` pour créer une table, et un objet `QueryRequest` pour interroger une table ou un index. 

1. Exécutez la méthode appropriée fournie par le client, que vous avez créée à l'étape précédente. 

**Topics**
+ [Créer une table avec un index secondaire global](#GSILowLevelDotNet.CreateTableWithIndex)
+ [Décrire une table avec un index secondaire global](#GSILowLevelDotNet.DescribeTableWithIndex)
+ [Interroger un index secondaire global](#GSILowLevelDotNet.QueryAnIndex)
+ [Exemple : index secondaires globaux utilisant l'API de AWS SDK pour .NET bas niveau](GSILowLevelDotNet.Example.md)

## Créer une table avec un index secondaire global
<a name="GSILowLevelDotNet.CreateTableWithIndex"></a>

Vous pouvez créer des index secondaires globaux au moment où vous créez une table. Pour ce faire, utilisez `CreateTable` et fournissez vos spécifications pour un ou plusieurs index secondaires globaux. L'exemple de code C\$1 suivant crée une table destinée à accueillir des données météorologiques. La clé de partition est `Location`, et la clé de tri `Date`. Un index secondaire global nommé `PrecipIndex` permet un accès rapide aux données de précipitations pour différents endroits.

Voici les étapes à suivre pour créer une table avec un index secondaire global à l'aide de l'API de bas niveau .NET. 

1. Créez une instance de la classe `AmazonDynamoDBClient`.

1. Créez une instance de la classe `CreateTableRequest` pour fournir l'information de requête. 

   Vous devez fournir le nom de la table, sa clé primaire et les valeurs de débit approvisionné. Pour l'index secondaire global, vous devez fournir le nom de l'index, ses paramètres de débit approvisionné, les définitions d'attribut pour la clé de tri d'index, le schéma de clé pour l'index et la projection d'attribut.

1. Exécutez la méthode `CreateTable` en fournissant l'objet de demande comme paramètre.

L’exemple de code C\$1 suivant illustre les étapes précédentes. Le code crée une table (`WeatherData`) avec un index secondaire global (`PrecipIndex`). La clé de partition d'index est `Date`, et la clé de tri `Precipitation`. Tous les attributs de table sont projetés sur l'index. Les utilisateurs peuvent interroger cet index afin d'obtenir des données météorologiques pour une date particulière, en triant éventuellement les données par quantité de précipitations. 

`Precipitation` n'étant pas un attribut de clé pour la table, il n'est pas obligatoire. Toutefois, les éléments `WeatherData` sans `Precipitation` n'apparaissent pas dans `PrecipIndex`.

```
client = new AmazonDynamoDBClient();
string tableName = "WeatherData";

// Attribute definitions
var attributeDefinitions = new List<AttributeDefinition>()
{
    {new AttributeDefinition{
        AttributeName = "Location",
        AttributeType = "S"}},
    {new AttributeDefinition{
        AttributeName = "Date",
        AttributeType = "S"}},
    {new AttributeDefinition(){
        AttributeName = "Precipitation",
        AttributeType = "N"}
    }
};

// Table key schema
var tableKeySchema = new List<KeySchemaElement>()
{
    {new KeySchemaElement {
        AttributeName = "Location",
        KeyType = "HASH"}},  //Partition key
    {new KeySchemaElement {
        AttributeName = "Date",
        KeyType = "RANGE"}  //Sort key
    }
};

// PrecipIndex
var precipIndex = new GlobalSecondaryIndex
{
    IndexName = "PrecipIndex",
    ProvisionedThroughput = new ProvisionedThroughput
    {
        ReadCapacityUnits = (long)10,
        WriteCapacityUnits = (long)1
    },
    Projection = new Projection { ProjectionType = "ALL" }
};

var indexKeySchema = new List<KeySchemaElement> {
    {new KeySchemaElement { AttributeName = "Date", KeyType = "HASH"}},  //Partition key
    {new KeySchemaElement{AttributeName = "Precipitation",KeyType = "RANGE"}}  //Sort key
};

precipIndex.KeySchema = indexKeySchema;

CreateTableRequest createTableRequest = new CreateTableRequest
{
    TableName = tableName,
    ProvisionedThroughput = new ProvisionedThroughput
    {
        ReadCapacityUnits = (long)5,
        WriteCapacityUnits = (long)1
    },
    AttributeDefinitions = attributeDefinitions,
    KeySchema = tableKeySchema,
    GlobalSecondaryIndexes = { precipIndex }
};

CreateTableResponse response = client.CreateTable(createTableRequest);
Console.WriteLine(response.CreateTableResult.TableDescription.TableName);
Console.WriteLine(response.CreateTableResult.TableDescription.TableStatus);
```

Vous devez attendre que DynamoDB crée la table et définisse l'état de celle-ci sur `ACTIVE`. Après cela, vous pouvez commencer à insérer des éléments de données dans la table.

## Décrire une table avec un index secondaire global
<a name="GSILowLevelDotNet.DescribeTableWithIndex"></a>

Pour obtenir des informations concernant les index secondaires globaux sur une table, utilisez l'opération `DescribeTable`. Pour chaque index, vous pouvez accéder à son nom, à son schéma de clé et aux attributs projetés.

Voici les étapes à suivre pour accéder aux informations d'index secondaire global pour une table à l'aide de l'API de bas niveau .NET. 

1. Créez une instance de la classe `AmazonDynamoDBClient`.

1. Exécutez la méthode `describeTable` en fournissant l'objet de demande comme paramètre.

   Créez une instance de la classe `DescribeTableRequest` pour fournir l'information de requête. Vous devez fournir le nom de la table.

L’exemple de code C\$1 suivant illustre les étapes précédentes.

**Example**  

```
client = new AmazonDynamoDBClient();
string tableName = "WeatherData";

DescribeTableResponse response = client.DescribeTable(new DescribeTableRequest { TableName = tableName});

List<GlobalSecondaryIndexDescription> globalSecondaryIndexes =
response.DescribeTableResult.Table.GlobalSecondaryIndexes;

// This code snippet will work for multiple indexes, even though
// there is only one index in this example.

foreach (GlobalSecondaryIndexDescription gsiDescription in globalSecondaryIndexes) {
     Console.WriteLine("Info for index " + gsiDescription.IndexName + ":");

     foreach (KeySchemaElement kse in gsiDescription.KeySchema) {
          Console.WriteLine("\t" + kse.AttributeName + ": key type is " + kse.KeyType);
     }

      Projection projection = gsiDescription.Projection;
      Console.WriteLine("\tThe projection type is: " + projection.ProjectionType);

      if (projection.ProjectionType.ToString().Equals("INCLUDE")) {
           Console.WriteLine("\t\tThe non-key projected attributes are: "
                + projection.NonKeyAttributes);
      }
}
```

## Interroger un index secondaire global
<a name="GSILowLevelDotNet.QueryAnIndex"></a>

Vous pouvez utiliser l'opération `Query` sur un index secondaire global de la même manière que vous utilisez l'opération `Query` sur une table. Vous devez spécifier le nom de l'index, les critères de requête pour la clé de partition d'index et la clé de tri (le cas échéant), ainsi que les attributs que vous souhaitez renvoyer. Dans cet exemple, l'index est `PrecipIndex`. Il a une clé de partition `Date` et une clé de tri `Precipitation`. L'interrogation de l'index renvoie toutes les données météorologiques pour une date particulière, où les précipitations sont supérieures à zéro.

Voici les étapes à suivre pour interroger un index secondaire global à l'aide de l'API de bas niveau .NET. 

1. Créez une instance de la classe `AmazonDynamoDBClient`.

1. Créez une instance de la classe `QueryRequest` pour fournir l'information de requête.

1. Exécutez la méthode `query` en fournissant l'objet de demande comme paramètre.

Nom d'attribut `Date` est un mot réservé DynamoDB. Par conséquent, vous devez utiliser un nom d'attribut d'expression comme espace réservé dans la `KeyConditionExpression`.

L’exemple de code C\$1 suivant illustre les étapes précédentes.

**Example**  

```
client = new AmazonDynamoDBClient();

QueryRequest queryRequest = new QueryRequest
{
    TableName = "WeatherData",
    IndexName = "PrecipIndex",
    KeyConditionExpression = "#dt = :v_date and Precipitation > :v_precip",
    ExpressionAttributeNames = new Dictionary<String, String> {
        {"#dt", "Date"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
        {":v_date", new AttributeValue { S =  "2013-08-01" }},
        {":v_precip", new AttributeValue { N =  "0" }}
    },
    ScanIndexForward = true
};

var result = client.Query(queryRequest);

var items = result.Items;
foreach (var currentItem in items)
{
    foreach (string attr in currentItem.Keys)
    {
        Console.Write(attr + "---> ");
        if (attr == "Precipitation")
        {
            Console.WriteLine(currentItem[attr].N);
    }
    else
    {
        Console.WriteLine(currentItem[attr].S);
    }

         }
     Console.WriteLine();
}
```

# Exemple : index secondaires globaux utilisant l'API de AWS SDK pour .NET bas niveau
<a name="GSILowLevelDotNet.Example"></a>

L'exemple de code C\$1 suivant montre comment utiliser des index secondaires globaux. L'exemple crée une table nommée `Issues`, utilisable dans un système simple de suivi de bogues pour le développement de logiciels. La clé de partition est `IssueId`, et la clé de tri `Title`. Il y a trois index secondaires globaux sur cette table :
+ `CreateDateIndex` – La clé de partition est `CreateDate`, et la clé de tri `IssueId`. En plus des clés de table, les attributs `Description` et `Status` sont projetés dans l'index.
+ `TitleIndex` – La clé de partition est `Title`, et la clé de tri `IssueId`. Aucun attribut autre que les clés de table n'est projeté dans l'index.
+ `DueDateIndex` – La clé de partition est `DueDate` et il n'y a pas de clé de tri. Tous les attributs de table sont projetés sur l'index.

Une fois la table `Issues` créée, le programme charge la table avec des données représentant des rapports de bogues logiciels. Il interroge ensuite les données à l'aide d'index secondaires globaux. Enfin, le programme supprime la table `Issues`.

Pour step-by-step obtenir des instructions sur le test de l'échantillon suivant, reportez-vous à[Exemples de code .NET](CodeSamples.DotNet.md).

**Example**  

```
using System;
using System.Collections.Generic;
using System.Linq;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.DocumentModel;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;
using Amazon.SecurityToken;

namespace com.amazonaws.codesamples
{
    class LowLevelGlobalSecondaryIndexExample
    {
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();
        public static String tableName = "Issues";

        public static void Main(string[] args)
        {
            CreateTable();
            LoadData();

            QueryIndex("CreateDateIndex");
            QueryIndex("TitleIndex");
            QueryIndex("DueDateIndex");

            DeleteTable(tableName);

            Console.WriteLine("To continue, press enter");
            Console.Read();
        }

        private static void CreateTable()
        {
            // Attribute definitions
            var attributeDefinitions = new List<AttributeDefinition>()
        {
            {new AttributeDefinition {
                 AttributeName = "IssueId", AttributeType = "S"
             }},
            {new AttributeDefinition {
                 AttributeName = "Title", AttributeType = "S"
             }},
            {new AttributeDefinition {
                 AttributeName = "CreateDate", AttributeType = "S"
             }},
            {new AttributeDefinition {
                 AttributeName = "DueDate", AttributeType = "S"
             }}
        };

            // Key schema for table
            var tableKeySchema = new List<KeySchemaElement>() {
            {
                new KeySchemaElement {
                    AttributeName= "IssueId",
                    KeyType = "HASH" //Partition key
                }
            },
            {
                new KeySchemaElement {
                    AttributeName = "Title",
                    KeyType = "RANGE" //Sort key
                }
            }
        };

            // Initial provisioned throughput settings for the indexes
            var ptIndex = new ProvisionedThroughput
            {
                ReadCapacityUnits = 1L,
                WriteCapacityUnits = 1L
            };

            // CreateDateIndex
            var createDateIndex = new GlobalSecondaryIndex()
            {
                IndexName = "CreateDateIndex",
                ProvisionedThroughput = ptIndex,
                KeySchema = {
                new KeySchemaElement {
                    AttributeName = "CreateDate", KeyType = "HASH" //Partition key
                },
                new KeySchemaElement {
                    AttributeName = "IssueId", KeyType = "RANGE" //Sort key
                }
            },
                Projection = new Projection
                {
                    ProjectionType = "INCLUDE",
                    NonKeyAttributes = {
                    "Description", "Status"
                }
                }
            };

            // TitleIndex
            var titleIndex = new GlobalSecondaryIndex()
            {
                IndexName = "TitleIndex",
                ProvisionedThroughput = ptIndex,
                KeySchema = {
                new KeySchemaElement {
                    AttributeName = "Title", KeyType = "HASH" //Partition key
                },
                new KeySchemaElement {
                    AttributeName = "IssueId", KeyType = "RANGE" //Sort key
                }
            },
                Projection = new Projection
                {
                    ProjectionType = "KEYS_ONLY"
                }
            };

            // DueDateIndex
            var dueDateIndex = new GlobalSecondaryIndex()
            {
                IndexName = "DueDateIndex",
                ProvisionedThroughput = ptIndex,
                KeySchema = {
                new KeySchemaElement {
                    AttributeName = "DueDate",
                    KeyType = "HASH" //Partition key
                }
            },
                Projection = new Projection
                {
                    ProjectionType = "ALL"
                }
            };



            var createTableRequest = new CreateTableRequest
            {
                TableName = tableName,
                ProvisionedThroughput = new ProvisionedThroughput
                {
                    ReadCapacityUnits = (long)1,
                    WriteCapacityUnits = (long)1
                },
                AttributeDefinitions = attributeDefinitions,
                KeySchema = tableKeySchema,
                GlobalSecondaryIndexes = {
                createDateIndex, titleIndex, dueDateIndex
            }
            };

            Console.WriteLine("Creating table " + tableName + "...");
            client.CreateTable(createTableRequest);

            WaitUntilTableReady(tableName);
        }

        private static void LoadData()
        {
            Console.WriteLine("Loading data into table " + tableName + "...");

            // IssueId, Title,
            // Description,
            // CreateDate, LastUpdateDate, DueDate,
            // Priority, Status

            putItem("A-101", "Compilation error",
                "Can't compile Project X - bad version number. What does this mean?",
                "2013-11-01", "2013-11-02", "2013-11-10",
                1, "Assigned");

            putItem("A-102", "Can't read data file",
                "The main data file is missing, or the permissions are incorrect",
                "2013-11-01", "2013-11-04", "2013-11-30",
                2, "In progress");

            putItem("A-103", "Test failure",
                "Functional test of Project X produces errors",
                "2013-11-01", "2013-11-02", "2013-11-10",
                1, "In progress");

            putItem("A-104", "Compilation error",
                "Variable 'messageCount' was not initialized.",
                "2013-11-15", "2013-11-16", "2013-11-30",
                3, "Assigned");

            putItem("A-105", "Network issue",
                "Can't ping IP address 127.0.0.1. Please fix this.",
                "2013-11-15", "2013-11-16", "2013-11-19",
                5, "Assigned");
        }

        private static void putItem(
            String issueId, String title,
            String description,
            String createDate, String lastUpdateDate, String dueDate,
            Int32 priority, String status)
        {
            Dictionary<String, AttributeValue> item = new Dictionary<string, AttributeValue>();

            item.Add("IssueId", new AttributeValue
            {
                S = issueId
            });
            item.Add("Title", new AttributeValue
            {
                S = title
            });
            item.Add("Description", new AttributeValue
            {
                S = description
            });
            item.Add("CreateDate", new AttributeValue
            {
                S = createDate
            });
            item.Add("LastUpdateDate", new AttributeValue
            {
                S = lastUpdateDate
            });
            item.Add("DueDate", new AttributeValue
            {
                S = dueDate
            });
            item.Add("Priority", new AttributeValue
            {
                N = priority.ToString()
            });
            item.Add("Status", new AttributeValue
            {
                S = status
            });

            try
            {
                client.PutItem(new PutItemRequest
                {
                    TableName = tableName,
                    Item = item
                });
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void QueryIndex(string indexName)
        {
            Console.WriteLine
                ("\n***********************************************************\n");
            Console.WriteLine("Querying index " + indexName + "...");

            QueryRequest queryRequest = new QueryRequest
            {
                TableName = tableName,
                IndexName = indexName,
                ScanIndexForward = true
            };


            String keyConditionExpression;
            Dictionary<string, AttributeValue> expressionAttributeValues = new Dictionary<string, AttributeValue>();

            if (indexName == "CreateDateIndex")
            {
                Console.WriteLine("Issues filed on 2013-11-01\n");

                keyConditionExpression = "CreateDate = :v_date and begins_with(IssueId, :v_issue)";
                expressionAttributeValues.Add(":v_date", new AttributeValue
                {
                    S = "2013-11-01"
                });
                expressionAttributeValues.Add(":v_issue", new AttributeValue
                {
                    S = "A-"
                });
            }
            else if (indexName == "TitleIndex")
            {
                Console.WriteLine("Compilation errors\n");

                keyConditionExpression = "Title = :v_title and begins_with(IssueId, :v_issue)";
                expressionAttributeValues.Add(":v_title", new AttributeValue
                {
                    S = "Compilation error"
                });
                expressionAttributeValues.Add(":v_issue", new AttributeValue
                {
                    S = "A-"
                });

                // Select
                queryRequest.Select = "ALL_PROJECTED_ATTRIBUTES";
            }
            else if (indexName == "DueDateIndex")
            {
                Console.WriteLine("Items that are due on 2013-11-30\n");

                keyConditionExpression = "DueDate = :v_date";
                expressionAttributeValues.Add(":v_date", new AttributeValue
                {
                    S = "2013-11-30"
                });

                // Select
                queryRequest.Select = "ALL_PROJECTED_ATTRIBUTES";
            }
            else
            {
                Console.WriteLine("\nNo valid index name provided");
                return;
            }

            queryRequest.KeyConditionExpression = keyConditionExpression;
            queryRequest.ExpressionAttributeValues = expressionAttributeValues;

            var result = client.Query(queryRequest);
            var items = result.Items;
            foreach (var currentItem in items)
            {
                foreach (string attr in currentItem.Keys)
                {
                    if (attr == "Priority")
                    {
                        Console.WriteLine(attr + "---> " + currentItem[attr].N);
                    }
                    else
                    {
                        Console.WriteLine(attr + "---> " + currentItem[attr].S);
                    }
                }
                Console.WriteLine();
            }
        }

        private static void DeleteTable(string tableName)
        {
            Console.WriteLine("Deleting table " + tableName + "...");
            client.DeleteTable(new DeleteTableRequest
            {
                TableName = tableName
            });
            WaitForTableToBeDeleted(tableName);
        }

        private static void WaitUntilTableReady(string tableName)
        {
            string status = null;
            // Let us wait until table is created. Call DescribeTable.
            do
            {
                System.Threading.Thread.Sleep(5000); // Wait 5 seconds.
                try
                {
                    var res = client.DescribeTable(new DescribeTableRequest
                    {
                        TableName = tableName
                    });

                    Console.WriteLine("Table name: {0}, status: {1}",
                              res.Table.TableName,
                              res.Table.TableStatus);
                    status = res.Table.TableStatus;
                }
                catch (ResourceNotFoundException)
                {
                    // DescribeTable is eventually consistent. So you might
                    // get resource not found. So we handle the potential exception.
                }
            } while (status != "ACTIVE");
        }

        private static void WaitForTableToBeDeleted(string tableName)
        {
            bool tablePresent = true;

            while (tablePresent)
            {
                System.Threading.Thread.Sleep(5000); // Wait 5 seconds.
                try
                {
                    var res = client.DescribeTable(new DescribeTableRequest
                    {
                        TableName = tableName
                    });

                    Console.WriteLine("Table name: {0}, status: {1}",
                              res.Table.TableName,
                              res.Table.TableStatus);
                }
                catch (ResourceNotFoundException)
                {
                    tablePresent = false;
                }
            }
        }
    }
}
```