Amazon dynamodb 在AppSync解析器中使用多个字段查询DynamoDB

Amazon dynamodb 在AppSync解析器中使用多个字段查询DynamoDB,amazon-dynamodb,aws-appsync,vtl,Amazon Dynamodb,Aws Appsync,Vtl,我有一个DynamoDB消息表,其中包含id、content、createdAt(int)、userID字段 我可以使用以下解析器获取用户的消息: { "version" : "2017-02-28", "operation" : "Query", "index" : "userid-createdat-index", "query&q

我有一个DynamoDB消息表,其中包含
id、content、createdAt(int)、userID
字段

我可以使用以下解析器获取用户的消息:

{
    "version" : "2017-02-28",
    "operation" : "Query",
    "index" : "userid-createdat-index",
    "query" : {
      "expression": "userID = :userID",
        "expressionValues" : {
          ":userID" : $util.dynamodb.toDynamoDBJson($context.arguments.userID)
        }
    }
}
我的目标是使用createdAt字段(以毫秒为单位的历元时间)在最后5秒内获取用户消息。我想避免使用扫描操作,因为我的表会很大


我该怎么做?我需要什么类型的DynamoDB索引?

假设
id
字段是唯一的,您需要在
id
上创建表分区键,然后在(userID,createdAt)上创建全局二级索引。访问您正在查找的结果的查询应该类似于以下内容:关键条件表达式“userID=:userID和createdAt>=:createdAt”

表创建

aws dynamodb create-table \
--table-name messages \
--attribute-definitions \
AttributeName=id,AttributeType=S \
AttributeName=userID,AttributeType=S \
AttributeName=createdAt,AttributeType=N \
--key-schema AttributeName=id,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=10,WriteCapacityUnits=5 \
--global-secondary-indexes \
"[{\"IndexName\": \"UserIDIndex\",
\"KeySchema\": [{\"AttributeName\":\"userID\",\"KeyType\":\"HASH\"},
{\"AttributeName\":\"createdAt\",\"KeyType\":\"RANGE\"}],
\"Projection\":{\"ProjectionType\":\"ALL\"},
\"ProvisionedThroughput\":     {\"ReadCapacityUnits\":10,\"WriteCapacityUnits\":10}}]"
使用GSI的示例查询

aws dynamodb query \
--table-name messages \
--index-name UserIDIndex \
--key-condition-expression "userID = :userID and createdAt >= :createdAt" \
--expression-attribute-values '{":userID":{"S":"u1"} , ":createdAt":{"N":"2"} }'
更多关于GSI的信息可以找到


如果您在本地运行DynamoDB,则可以添加
--端点urlhttp://localhost:8000
以上两段代码。

根据CruncherBigData回答中的建议,我成功地运行了这样一个查询

我用userID的分区键和createdAt的排序键创建了一个索引。我的错误是在创建索引时忘记选择Number作为createdAt的数据类型。将其保留为字符串失败了我的查询

然后,我使用查询解析器在最后5秒内检查用户的消息:

#set( $messageTimeLimit = 5000 )
#set( $lastNSeconds = $util.time.nowEpochMilliSeconds() - $messageTimeLimit )
{
    "version" : "2018-05-29",
    "operation" : "Query",
    "index" : "userID-createdAt-index",
    "query" : {
      "expression": "userID = :userID and createdAt >= :lastFiveSeconds",
        "expressionValues" : {
          ":lastFiveSeconds" : $util.dynamodb.toDynamoDBJson($lastFiveSeconds),
          ":userID" : $util.dynamodb.toDynamoDBJson($context.arguments.userID)
        }
    }
}