Query sur un GSI DynamoDB avec l'AWS CLI
Interroger un index secondaire global, c'est un aws dynamodb query normal plus un flag : --index-name. La condition de clé vise alors les clés de l'index, pas celles de la table — ici, AlbumTitle-index nous permet de récupérer les morceaux par album, un modèle d'accès que la table de base (Artist + SongTitle) ne peut pas servir sans un scan.
Code
aws dynamodb query \
--table-name 'Music' \
--index-name 'AlbumTitle-index' \
--key-condition-expression '#hashKey = :hashKeyValue' \
--expression-attribute-names '{"#hashKey":"AlbumTitle"}' \
--expression-attribute-values '{":hashKeyValue":{"S":"Danzon"}}'La sortie, ce sont les éléments correspondants en JSON DynamoDB :
{
"Items": [
{"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}, ...}
],
"Count": 2,
"ScannedCount": 2
}Explication
La table de base n'est facturée en rien pour cette requête. Ajoute --return-consumed-capacity INDEXES et la répartition devient explicite :
"ConsumedCapacity": {
"CapacityUnits": 132.0,
"Table": {"CapacityUnits": 0.0},
"GlobalSecondaryIndexes": {"AlbumTitle-index": {"CapacityUnits": 132.0}}
}Zéro pour la table, tout pour l'index. Un GSI est une table à part avec son propre schéma de clé, ses propres partitions et sa propre capacité, et le lire ne touche jamais la table de base. C'est aussi pour ça qu'un GSI a son propre régime de throttling : un GSI limité peut limiter les écritures de la table de base alors même que les lectures ne traversent jamais.
--consistent-read est rejeté, pas rétrogradé. Les GSI se répliquent de façon asynchrone, et aucun flag n'y change quoi que ce soit :
aws: [ERROR]: An error occurred (ValidationException) when calling the Query operation: Consistent reads are not supported on global secondary indexesCode de sortie 254. La référence de l'API le dit d'avance : "Strongly consistent reads are not supported on global secondary indexes. If you query a global secondary index with ConsistentRead set to true, you will receive a ValidationException" (consultée le 2026-07-28). Les index secondaires locaux, eux, l'acceptent, ce qui est l'une des rares vraies raisons de choisir un LSI. Le décalage lui-même est traité dans pourquoi les GSI sont en cohérence à terme.
Les éléments sans clé d'index ne sont tout simplement pas dans l'index. Comptés sur la même table : 35 éléments dans la table de base, 32 dans AlbumTitle-index. Les trois manquants n'ont aucun attribut AlbumTitle, confirmé par un scan sur attribute_not_exists(AlbumTitle). Rien n'a échoué et rien n'a averti. C'est le motif de l'index creux, et c'est une conception délibérée quand tu n'écris l'attribut drapeau que pour les lignes que tu veux indexer — et un bug de perte de données silencieuse quand tu supposes que l'index reflète la table.
Tu n'obtiens que ce que l'index projette. "If you query or scan a global secondary index, you can only request attributes that are projected into the index. Global secondary index queries cannot fetch attributes from the parent table" (consulté le 2026-07-28). Sur un index KEYS_ONLY ou INCLUDE, ça veut dire un second get-item par résultat pour compléter le reste, c'est-à-dire le N+1 que tu essayais d'éviter. La projection est figée à la création de l'index et ne peut plus être changée ensuite ; voir les projections d'index avant d'en choisir une.
Les clés d'index ne sont pas uniques. Beaucoup d'éléments peuvent partager un même AlbumTitle : une requête sur un GSI renvoie donc une collection là où la requête équivalente sur la table renverrait un seul élément. Il n'existe pas de get-item sur un GSI, exactement pour cette raison.
La pagination se comporte comme sur n'importe quelle requête de table, y compris l'habitude qu'a la CLI de rapporter la ConsumedCapacity d'une seule page pour un résultat auto-paginé. C'est mesuré en détail dans Query avec l'AWS CLI ; les flags sont les mêmes ici.
Le faire visuellement
Une requête sur un index a plus de pièces mobiles qu'une requête sur une table : le bon index, les noms de clés propres à l'index, et une projection qui peut ne pas porter les attributs dont tu as besoin. Le DynamoDB Query Builder gratuit te laisse choisir l'index, construit la condition de clé sur ses clés, et produit la commande CLI.
Pour voir quels index une table possède réellement et les interroger sur tes propres données — projections listées, grille qui pagine au défilement, requête recopiée en commande CLI — télécharge DynoTable.
Exemples liés
- Query sur un GSI DynamoDB en Node.js — la même requête d'index avec l'AWS SDK v3.
- Query sur un GSI DynamoDB en Python — la même requête d'index avec boto3.
- GSI vs LSI — quel type d'index convient au modèle d'accès.
- "The table does not have the specified index" — le nom de l'index ne correspond pas (les noms de GSI sont sensibles à la casse).
- "Consistent reads are not supported on global secondary indexes" — pourquoi le flag de lecture fortement cohérente échoue sur un GSI.
Références
- Query — Amazon DynamoDB API Reference
- query — AWS CLI Command Reference
- Using Global Secondary Indexes in DynamoDB — Amazon DynamoDB Developer Guide
- Using AWS CLI pagination options — AWS CLI User Guide
Reproduit le 2026-07-28 avec aws-cli/2.36.9 sur DynamoDB Local (amazon/dynamodb-local) sur le port 9000, sur une table Music dotée d'un AlbumTitle-index projetant ALL. Le texte de l'erreur, la répartition de capacité et le décompte des éléments sont la sortie capturée.