【问题标题】:Querying DynamoDB with multiple fields in an AppSync Resolver在 AppSync 解析器中使用多个字段查询 DynamoDB
【发布时间】:2021-04-04 05:40:35
【问题描述】:

我有一个带有 id, content, createdAt (int), userID 字段的 DynamoDB 消息表。

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

{
    "version" : "2017-02-28",
    "operation" : "Query",
    "index" : "userid-createdat-index",
    "query" : {
      "expression": "userID = :userID",
        "expressionValues" : {
          ":userID" : $util.dynamodb.toDynamoDBJson($context.arguments.userID)
        }
    }
}

我的目标是使用 createdAt 字段在最后 5 秒内获取用户消息,该字段是以毫秒为单位的纪元时间。我想避免使用 Scan 操作,因为我的表会很大。

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

【问题讨论】:

    标签: amazon-dynamodb aws-appsync vtl


    【解决方案1】:

    假设 id 字段是唯一的,您需要在 id 上创建表分区键,然后在 (userID , createdAt) 上创建全局二级索引。访问您正在查找的结果的查询应该类似于 --key-condition-expression "userID = :userID and 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 的更多信息可以找到here

    如果您在本地运行 DynamoDB,您可以将--endpoint-url http://localhost:8000 添加到上述两个代码 sn-ps。

    【讨论】:

      【解决方案2】:

      使用来自 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)
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-07-18
        • 2018-12-15
        • 2020-01-03
        • 2021-12-27
        • 2019-02-04
        • 2019-04-16
        • 2020-11-19
        • 1970-01-01
        • 2020-02-12
        相关资源
        最近更新 更多