La consulta de DynamoDB no devuelve ningún elemento con un filtro y un límite de 1.
Tengo la siguiente tabla dynamoDB:
user_id | fecha | juego |
---|---|---|
user1 | 2021-12-06 14:36:46 | game1 |
user1 | 2021-12-06 15:36:46 | game1 |
user1 | 2021-12-07 11:36:46 | game2 |
user1 | 2021-12-07 12:36:46 | game2 |
Clave de partición: user_id
Clave de clasificación: fecha
Quiero consultar la última entrada del usuario para el juego “game1”
(que es el segundo elemento de la tabla con la fecha “2021-12-06 15:36:46”). Puedo lograr esto mediante el siguiente código:
expr, _ := expression.NewBuilder().
WithKeyCondition(expression.Key("user_id").Equal(expression.Value("user1"))).
WithFilter(expression.Name("game").Equal(expression.Value("game1"))).
Build()
var queryInput = &dynamodb.QueryInput{
KeyConditionExpression: expr.KeyCondition(),
ExpressionAttributeNames: expr.Names(),
ExpressionAttributeValues: expr.Values(),
FilterExpression: expr.Filter(),
ScanIndexForward: aws.Bool(false),
TableName: aws.String(table),
}
Esto me devuelve todos los elementos del usuario “user1” para el juego “game1”. El problema ocurre cuando aplico el límite de 1 Limit: aws.Int64(1)
en la QueryInput, no devuelve nada. ¿Podría alguien explicar por qué ocurre esto?
Cuando cambio el límite a Limit: aws.Int64(4)
(número total de elementos en la tabla), solo entonces la consulta devuelve un único elemento esperado. ¿Cómo funciona este límite?
¿Necesito utilizar “game” como GSI (índice secundario global)?
davy.ai
La razón por la que aplicar
Limit: aws.Int64(1)
enQueryInput
no devuelve el resultado esperado es que el límite se aplica después de que se ejecuta la consulta, lo que significa que DynamoDB seguirá devolviendo todos los elementos que coinciden con los criterios de la consulta antes de aplicar el límite.En este caso, aplicar un límite de 1 significa que DynamoDB solo devolverá el primer elemento del conjunto de resultados, independientemente de si coincide con el filtro de la consulta. Como resultado, si el primer elemento que DynamoDB devuelve no coincide con el filtro, la consulta devolverá un conjunto de resultados vacío.
Para resolver este problema, puedes utilizar un índice secundario global (GSI) que incluya
game
como clave de partición ydate
como clave de ordenación. Con este GSI, puedes consultar la última entrada del usuario para el juegogame1
de la siguiente manera:En este caso, la consulta utiliza el GSI para recuperar solo los elementos que coinciden con el filtro (“game1”), ordenados en orden descendente según el atributo
date
. El parámetroLimit
se aplica después de la consulta, por lo que la consulta solo devolverá el primer elemento que coincida con el filtro.Ten en cuenta que agregar un GSI también implica costos adicionales y proporciona capacidad adicional de rendimiento. Por lo tanto, debes considerar si es necesario agregar un GSI o si modificar el modelo de datos podría lograr el mismo resultado sin incurrir en estos costos.