代码之家  ›  专栏  ›  技术社区  ›  OCDev

如何在DynamoDB Go SDK中为一组分区值的分区键编写条件相同但排序键为MAX的查询?

  •  0
  • OCDev  · 技术社区  · 4 年前

    我在DynamoDB中有一个带有复合键的表

    user_id(分区密钥) 时间戳(排序键)

    我想检索一组项目,我有一组要检索的user_id,但我还需要时间戳是每个user_id的最大值。

    例如:

    user_id 时间戳 attr
    1. 1614910613 值1
    1. 1614902527 值2
    2. 1614910683 值2
    2. 1614881311 值2
    3. 1614902527 值2

    我想检索user_id 1和2的行,以及每个用户的最大时间戳。在这种情况下,我的结果集应该是:

    user_id 时间戳 attr
    1. 1614910613 值1
    2. 1614910683 值2

    我现在可以逐一执行以下Key表达式:

    cond := expression.KeyAnd(
        expression.Key("user_id").Equal(expression.Value(userId)),
        expression.Key("timestamp").LessThanEqual(expression.Value(int32(time.Now().Unix()))),
        )
    expr, err:= expression.NewBuilder().WithKeyCondition(cond).Build()
    
    if err!=nil {
        panic(err)
    }
    
    input := &dynamodb.QueryInput{
        ExpressionAttributeNames: expr.Names(),
        ExpressionAttributeValues: expr.Values(),
        KeyConditionExpression: expr.KeyCondition(),
        TableName: aws.String("td.notes"),
        Limit: aws.Int64(1),
        ScanIndexForward: aws.Bool(false),
    }
    

    我的问题是,我不知道如何为user_id键传递一组值,而不是单个值。我看了BatchGetItem,我知道我可以做这样的事情:

    mapOfAttrKeys := []map[string]*dynamodb.AttributeValue{}
    
    for _, place := range userIDs {
        mapOfAttrKeys = append(mapOfAttrKeys, map[string]*dynamodb.AttributeValue{
            "user_id": &dynamodb.AttributeValue{
                S: aws.String(place),
            },
            "timestamp": &dynamodb.AttributeValue{
                N: aws.String(timestamp),
            },
        })
    }
    
    input := &dynamodb.BatchGetItemInput{
        RequestItems: map[string]*dynamodb.KeysAndAttributes{
            tableName: &dynamodb.KeysAndAttributes{
                Keys: mapOfAttrKeys,
            },
        },
    }
    

    但我不能在时间戳中加入“小于”的条件。

    谢谢!

    0 回复  |  直到 4 年前
        1
  •  1
  •   Charles    4 年前

    GetItem和BatchGetItem需要精确的主键。

    您需要为每个要返回的用户发出单独的Query()。

    正如你所发现的,返回max的关键是

    Limit: aws.Int64(1),
    ScanIndexForward: aws.Bool(false),
    

    你真的不需要这个

    expression.Key("timestamp").LessThanEqual(expression.Value(int32(time.Now().Unix())))
    
    推荐文章