Query a un GSI de DynamoDB en Node.js (SDK de AWS v3)

Una consulta a un GSI es un Query normal más IndexName, y entonces dos cosas dejan de comportarse como en una consulta a la tabla: el flag de consistencia al que estás acostumbrado se convierte en un error, y el cursor de paginación gana un atributo extra. Aquí AlbumTitle-index recupera canciones por álbum, algo que la tabla base (Artist + SongTitle) no puede hacer sin un scan.

Código

import {DynamoDBClient, QueryCommand} from '@aws-sdk/client-dynamodb';

const client = new DynamoDBClient({region: 'us-east-1'});

const items = [];
let lastEvaluatedKey;

do {
  const response = await client.send(
    new QueryCommand({
      TableName: 'Music',
      IndexName: 'AlbumTitle-index',
      KeyConditionExpression: '#hashKey = :hashKeyValue',
      ExpressionAttributeNames: {
        '#hashKey': 'AlbumTitle'
      },
      ExpressionAttributeValues: {
        ':hashKeyValue': {S: 'Danzon'}
      },
      ExclusiveStartKey: lastEvaluatedKey
    })
  );

  items.push(...(response.Items ?? []));
  lastEvaluatedKey = response.LastEvaluatedKey;
} while (lastEvaluatedKey);

console.log(`Found ${items.length} songs on the album`);

El cursor tiene tres atributos de ancho, no dos

Ejecuta el bucle de arriba contra 300 canciones de un mismo álbum e inspecciona el LastEvaluatedKey que devuelve:

table query  -> ['Artist', 'SongTitle']
GSI query    -> ['AlbumTitle', 'Artist', 'SongTitle']

Una clave de GSI no es única, así que la clave del índice por sí sola no puede reanudar un recorrido. DynamoDB devuelve la clave del índice y la clave de la tabla base juntas, y ambas tienen que volver intactas en ExclusiveStartKey. Por eso un cursor artesanal que guarda «la última clave de ordenación que vi» funciona sobre una tabla y en silencio pierde o repite Items sobre un índice — y por eso persistir esa clave en un cliente es mala idea cuando la clave de la tabla es un id de usuario que preferirías no filtrar.

ConsistentRead: true es un 400, no una mejora

El instinto dice que una lectura fuertemente consistente cuesta más capacidad y te da datos más frescos. En un GSI te cuesta la petición:

ValidationException: Consistent reads are not supported on global secondary indexes
HTTP 400

La referencia de la API es igual de tajante: "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." Scan sobre un GSI rechaza el mismo flag con el mismo mensaje. Los índices secundarios locales sí lo aceptan.

Reproducido el 2026-07-28 contra DynamoDB Local (amazon/dynamodb-local) con @aws-sdk/client-dynamodb 3.1095.0 en node v24.18.0. El texto del error y las formas de las claves son la salida propia del motor.

Explicación

  • IndexName no sustituye a TableName. Ambos van en el mismo comando, y la KeyConditionExpression nombra entonces la clave de partición del índice (AlbumTitle), no la de la tabla, con el mismo juego de operadores que una consulta a la tabla.
  • Obtienes la proyección y nada más. Una consulta a un GSI devuelve lo que el índice proyecta (ALL, KEYS_ONLY o la lista INCLUDE), y según la referencia de la API "global secondary index queries cannot fetch attributes from the parent table". Un atributo que falte significa un GetItem de seguimiento sobre la clave base, o una proyección más amplia y un índice recreado.
  • Los Items a los que les falta la clave del índice nunca aparecen. Ese es el patrón de índice disperso, y es una característica: indexa solo las filas con status = "OPEN" y el GSI se mantiene pequeño. También es la razón por la que una consulta a un GSI puede devolver menos Items de los que esperas sin lanzar ningún error.
  • La replicación es asíncrona, así que una escritura que acaba de aterrizar en la tabla puede no estar todavía en el índice. Cuenta con eso en los caminos de lectura tras escritura en lugar de reintentar en un bucle cerrado.

Hazlo visualmente

Añadir un GSI a posteriori es la forma cara de aprender esto. La herramienta de diseño de tabla única toma tus patrones de acceso y determina cuáles necesitan una clave de índice y cuáles ya sirve la tabla base.

Para explorar los índices de una tabla y ejecutar consultas a un GSI desde un formulario, con una cuadrícula paginada, descarga DynoTable.

Ejemplos relacionados

Referencias

Construye esta solicitud visualmente

Compón esta operación en el Generador de consultas de DynamoDB gratuito —condición de clave, filtro, índice, Limit, orden de clasificación y un bucle de paginación— y cópiala de vuelta como un programa ejecutable para SDK v3, CLI o boto3.

Abrir el Generador de consultas de DynamoDB

Trabaja con DynamoDB sin la Consola

Un cliente de escritorio rápido para DynamoDB que ejecuta el SQL real que DynamoDB no puede — JOINs, GROUP BY, agregaciones — con edición visual y un agente de IA con tus propias claves de Bedrock.

Prueba gratuita de 30 días, sin tarjeta — después, el plan Free sin límite de tiempo.