es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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)?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    La razón por la que aplicar Limit: aws.Int64(1) en QueryInput 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 y date como clave de ordenación. Con este GSI, puedes consultar la última entrada del usuario para el juego game1 de la siguiente manera:

    expr, _ := expression.NewBuilder().
        WithKeyCondition(expression.Key("game").Equal(expression.Value("game1"))).
        Build()
    var queryInput = &dynamodb.QueryInput{
        KeyConditionExpression:    expr.KeyCondition(),
        ExpressionAttributeNames:  expr.Names(),
        ExpressionAttributeValues: expr.Values(),
        Limit:                     aws.Int64(1),
        ScanIndexForward:          aws.Bool(false),
        TableName:                 aws.String(table),
        IndexName:                 aws.String("game-date-index"),
    }
    
    

    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ámetro Limit 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.

Comments are closed.