繁体   English   中英

使用 FilterExpression PYTHON 限制和排序 DynamoDB 结果

[英]Limit and sort DynamoDB results with FilterExpression PYTHON

嗨,你能指导我如何使用过滤器表达式限制结果的数量。 我不能使用关键方法,需要按属性来使用过滤器。 请查看我下面的代码,在下面的代码中,它会返回 500 条记录作为响应,但我只需要获取 10 条最新记录

   import json
import boto3
from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('users')

def lambda_handler(event, context):
    response = table.scan(
        FilterExpression=Attr('age').eq('30') & Attr('created_at').lt('2020-01-01T00:00:00') & Attr('status').eq('enabled')
    )
    items = response['Items']
    #loadjson = json.stringify(event)
    #for data in event['data']:
    #    print(data['key'])
    return items   

根据使用扫描的文档,您可以使用Limit参数。 但是,这可能无法达到您的预期。

考虑以下:

  • 一次scan操作一次最多获取 1MB 的数据(更多的数据需要分页)
  • Limit参数设置您希望scan操作在筛选表达式计算之前返回的最大项目数。
  • FilterExpression确定应将扫描结果中的哪些项目返回给您。 所有其他结果都被丢弃。

重要部分:扫描操作首先应用Limit参数,然后应用FilterExpression ,然后返回结果。

为什么这很重要?

从文档:

...假设您扫描了一个限制值为 6 且没有过滤器表达式的表。 扫描结果包含表中的前六个项目。

现在假设您向 Scan 添加了一个过滤器表达式。 在这种情况下,DynamoDB 将过滤器表达式应用于返回的六个项目,丢弃那些不匹配的项目。 最终的扫描结果包含六个或更少的项目,具体取决于过滤的项目数量。

让我们再看看你的过滤器:

table.scan(
FilterExpression=Attr('age').eq('30') & Attr('created_at').lt('2020-01-01T00:00:00') & Attr('status').eq('enabled'))

此操作将从您的数据库中读取前 1MB 的数据,删除与过滤器不匹配的所有项目,然后将结果返回给您。 如果您的数据库大小大于 1MB,您将需要继续对结果进行分页,直到处理完整个数据库。 请记住,您可能会收到几个空的结果集,因为1MB限制应用FilterExpression和之前结果返回给你。

可能不是你想要的,对吧?

使用scan操作通常是数据模型设计不当的标志。 虽然scan有一些很好的用途,但这种访问模式听起来不像其中之一。 您可能需要仔细查看您的访问模式并创建支持此操作的二级索引。 否则,您将陷入更昂贵(在计算和财务上)的scan操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM