pmi*_*nda 2 amazon-dynamodb dynamodb-queries
我Limit对 DynamoDB 上的查询/扫描有疑问。
我的表有 1000 条记录,对所有记录的查询都返回 50 个值,但是如果我输入Limit5 个值,这并不意味着查询将返回前 5 个值,它只是说对 5 个项目的查询表(以任何顺序,所以它们可能是非常旧的项目或新项目),所以我有可能在查询中得到 0 个项目。如何实际获取查询的最新 5 项?我需要将 a 设置Limit为 5(数字是示例),因为查询/扫描比这更多的项目会很昂贵。
查询有这个输入
{
TableName: 'transactionsTable',
IndexName: 'transactionsByUserId',
ProjectionExpression: 'origin, receiver, #valid_status, createdAt, totalAmount',
KeyConditionExpression: 'userId = :userId',
ExpressionAttributeValues: {
':userId': 'user-id',
':payment_gateway': 'payment_gateway'
},
ExpressionAttributeNames: {
'#valid_status': 'status'
},
FilterExpression: '#valid_status = :payment_gateway',
Limit: 5
}
Run Code Online (Sandbox Code Playgroud)
我的表的索引是这样的:
我应该使用第二个索引或其他东西,用字段对它们进行排序,createdAt但是,我如何确定查询会查看所有项目?
如果我将限制设置为 5,这并不意味着查询将返回前 5 个值,它只是说查询表中的 5 个项目(以任何顺序,因此它们可能是非常旧的项目或新项目) ,所以我有可能在查询中得到 0 个项目。如何实际获取查询的最新 5 项?
您的观察是正确的,不幸的是,没有任何Query选项或任何其他操作可以保证单个请求中有 5 个项目。要理解为什么会这样(这不仅仅是亚马逊方面的懒惰),请考虑以下极端情况:您有一个包含 10 亿个项目的庞大数据库,但是执行一个只有 5 个匹配项目的非常具体的查询,现在使您想要的请求:“还我 5 件物品”。这样的请求需要读取整个数据库的 10 亿项,然后才能返回任何内容,届时客户端肯定会放弃。所以这不是 DyanmoDB 的Limit工作方式。它限制了 DynamoDB 在响应之前需要做的工作量。因此,如果Limit = 100, DynamoDB 将在内部读取 100 个项目,这需要一定的时间。但是您是对的,您不知道它是否会响应 100 个项目(如果它们都与过滤器匹配)或 0 个项目(如果它们都不与过滤器匹配)。
因此,要高效地做您想做的事情,您需要想出一种不同的方式来为您的数据建模——即,如何组织分区和对键进行排序。有不同的方法可以做到这一点,每种方法都有自己的优点和缺点,您需要自己考虑选择。既然您询问了 GSI,我会给您一些有关如何使用该选项的提示:
您正在寻找的模式称为过滤数据检索。正如您所指出的,如果您使用排序键执行 GSIcreatedAt,您可以先检索最新的项目。但是你仍然需要做一个过滤器,并且仍然不知道在5个过滤结果(而不是5个预过滤)结果之后如何停止。解决方案是要求 DynamoDB 首先只将通过过滤的项目放入 GSI。在您的示例中,您似乎总是使用相同的过滤器:“status = payment_gateway”。DynamoDB 在构建 GSI 时没有运行通用过滤器功能的选项,但它有一个不同的技巧来实现同样的事情:任何时候设置“status = payment_gateway”,同时设置另一个属性“status_payment_gateway” ,当状态设置为其他内容时,删除“status_payment_gateway”。现在,使用“status_payment_gateway”作为分区键创建 GSI. DynamoDB 只会将具有此属性的项目放入 GSI,从而准确实现您想要的过滤。
通过将分区键属性设置为多个不同的值,您还可以在一个 GSI 中拥有多个互斥的过滤条件,然后您可以Query分别对这些值中的每一个执行 a (使用KeyConditionExpression)。
| 归档时间: |
|
| 查看次数: |
750 次 |
| 最近记录: |