【问题标题】:DynamoDB - fetching items by multiple keysDynamoDB - 通过多个键获取项目
【发布时间】:2020-04-20 13:25:34
【问题描述】:

最近开始使用DynamoDB,我在通过多个键获取数据时遇到问题。

我正在尝试从一个表中获取多个项目。

我的表架构定义如下:

{
  "AttributeDefinitions": [
    {
      "AttributeName": "id",
      "AttributeType": "S"
    },
    {
      "AttributeName": "date",
      "AttributeType": "S"
    }
  ],
  "KeySchema": [
    {
      "AttributeName": "id",
      "KeyType": "HASH"
    },
    {
      "AttributeName": "date",
      "KeyType": "RANGE"
    }
  ],
  ...
}

我有一个 id 过滤器列表和每个 id 的日期范围:

[
    { "id": "abc", "start_date": "24/03/2020", "end_date": "26/03/2020" },
    { "id": "def", "start_date": "10/04/2020", "end_date": "20/04/2020" },
    { "id": "ghi", "start_date": "11/04/2020", "end_date": "11/04/2020" }
]

我需要获取与过滤列表匹配的所有项目。

问题是我不能使用Query 因为KeyConditionExpression 只接受一个分区键(我需要将它与整个过滤器列表匹配)

条件必须对单个分区键值执行相等测试。

我不能使用BatchGetItem,因为它需要确切的键(我需要一个日期范围作为排序键Key('date').between(start_date, end_date)

Keys - 定义表中特定项目的主键属性值数组。对于每个主键,您必须提供所有键属性。例如,使用简单的主键,您只需要提供分区键值。对于复合键,您必须同时提供分区键值和排序键值。

我有点迷茫... 有没有办法通过范围查询的多个键获取(通过单个请求 - 而不是来自循环的多个请求)?

您会建议更改表格吗?

【问题讨论】:

    标签: python amazon-dynamodb boto3 dynamodb-queries


    【解决方案1】:

    您需要对每个唯一的id 进行一次查询。这些查询中的每一个都应包含一个键条件表达式,该表达式在id 分区键和date 排序键上具有值范围,如下所示:

    #id = :id AND #date BETWEEN :startdate AND :enddate
    

    不要为此使用scan。随着表的增长,性能会下降。

    【讨论】:

    • 使用多个Query请求不是问题吗?例如,如果我需要按 20 个 id 过滤它,我最终会收到 20 个对表的请求,而不是 1 个具有多个 id 的请求,它会增加我的请求率......另一方面,我没有找到任何其他方式(除了scan 这不是这里的选项)所以我想这是唯一的选择..?
    • 因为您有多个分区键并且您的日期范围不同,我不知道有什么方法可以在一个查询中满足这一点。即使添加 GSI 也无济于事。但是,您可以并行进行查询,因为它们可能会遇到不同的分区,这将减少您的总延迟。
    【解决方案2】:

    您可以使用 table.scan 来获取多条记录。请参阅文档here

    这是一个示例代码:

    import boto3
    
    # Get the service resource.
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('tablename')
    
    response = table.scan(
    FilterExpression=Attr('first_name').begins_with('J') & Attr('account_type').eq('super_user')
    )
    items = response['Items']
    print(items)
    

    【讨论】:

    • 感谢您的回答!但是scan 操作非常“昂贵”,因为它在获取数据之后和返回之前应用过滤器 - 所以不幸的是,这不是我的选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多