扫描直到找到 x 个项目?
Scan until x items are found?
我正在编写查询以查找用户名以给定前缀开头的所有用户。我只想查询 return 最多 10 个项目。我现在的查询是
User.scan('username')
.beginsWith(req.query.prefix)
.limit(req.query.limit)
.exec((err, users) => {
...
});
在更仔细地阅读 .limit()
的 dynamoose docs 之后,我意识到限制是它检查的 table 个条目的数量,而不是它 return秒。因此,如果我有 10 个用户,其中 5 个用户的用户名以 'm' 开头,像 query: { prefix: 'm', limit: 5}
这样的查询可能会 return 0 个项目。
我知道我可以查询数据库中的所有用户,然后只查询其中的 return 部分用户,但它无法扩展。 我如何查询数据库,使其在找到 10 个匹配项时停止查找 table?
在 DynamoDB 中无法直接做您想做的事。正如您所发现的,“限制”选项表示要检查的项目数量 - 而不是 return 的数量。当出现这种需要时,通常做的是选择一些合理的页面大小,例如 1000 个项目或(如果您未指定数字,则为默认值)1MB 的项目,然后一次读取这样的页面大小。如果第一页的项目数已超过所需数量的 5 个,则停止扫描(并且不需要扫描整个 table)。如果第一页只找到一个匹配项目 returned,您将继续阅读其他页面 - 直到总共找到 5 个项目。
如果您好奇为什么 DynamoDB 没有直接请求“5 个匹配项”的选项,想象一下如果整个数据库的匹配项少于 5 个会发生什么。 DynamoDB 需要扫描整个 table 以在 return 任何东西之前查找前 5 个项目。如果这需要一个小时,那么客户在整整一个小时内都不会收到任何结果!数据库客户端通常不会以这种方式工作,它们会在一个小时过去之前超时。更重要的是,如果服务器在这个小时内重新启动,则工作将丢失且无法恢复。因此,对于 DynamoDB 的 API,服务器仅读取 1MB(或其他)数据块,并且在每个数据块之后,服务器 return 向客户端发送答案 "no data yet" - 并且客户端需要恢复扫描。有一些开销,但并不多(大概扫描 1MB 数据的工作量和成本比发送请求要多),并且避免了上述所有问题。
最后,关于您的用例的另一条评论:整个 table 扫描,就像您正在做的那样,非常 昂贵 - 无论是时间还是成本。如果您有一个包含 100 万个条目的 table 并且期望扫描仅产生 5 个项目,那么您将需要支付读取 100 万个条目的费用才能得到 5 个。如果这些查询很常见,您可能需要重新考虑您的数据模型,以便典型的查询只需要读取一项 - 或者最多只查询一个分区 - 而不是完整的 table 扫描。
我正在编写查询以查找用户名以给定前缀开头的所有用户。我只想查询 return 最多 10 个项目。我现在的查询是
User.scan('username')
.beginsWith(req.query.prefix)
.limit(req.query.limit)
.exec((err, users) => {
...
});
在更仔细地阅读 .limit()
的 dynamoose docs 之后,我意识到限制是它检查的 table 个条目的数量,而不是它 return秒。因此,如果我有 10 个用户,其中 5 个用户的用户名以 'm' 开头,像 query: { prefix: 'm', limit: 5}
这样的查询可能会 return 0 个项目。
我知道我可以查询数据库中的所有用户,然后只查询其中的 return 部分用户,但它无法扩展。 我如何查询数据库,使其在找到 10 个匹配项时停止查找 table?
在 DynamoDB 中无法直接做您想做的事。正如您所发现的,“限制”选项表示要检查的项目数量 - 而不是 return 的数量。当出现这种需要时,通常做的是选择一些合理的页面大小,例如 1000 个项目或(如果您未指定数字,则为默认值)1MB 的项目,然后一次读取这样的页面大小。如果第一页的项目数已超过所需数量的 5 个,则停止扫描(并且不需要扫描整个 table)。如果第一页只找到一个匹配项目 returned,您将继续阅读其他页面 - 直到总共找到 5 个项目。
如果您好奇为什么 DynamoDB 没有直接请求“5 个匹配项”的选项,想象一下如果整个数据库的匹配项少于 5 个会发生什么。 DynamoDB 需要扫描整个 table 以在 return 任何东西之前查找前 5 个项目。如果这需要一个小时,那么客户在整整一个小时内都不会收到任何结果!数据库客户端通常不会以这种方式工作,它们会在一个小时过去之前超时。更重要的是,如果服务器在这个小时内重新启动,则工作将丢失且无法恢复。因此,对于 DynamoDB 的 API,服务器仅读取 1MB(或其他)数据块,并且在每个数据块之后,服务器 return 向客户端发送答案 "no data yet" - 并且客户端需要恢复扫描。有一些开销,但并不多(大概扫描 1MB 数据的工作量和成本比发送请求要多),并且避免了上述所有问题。
最后,关于您的用例的另一条评论:整个 table 扫描,就像您正在做的那样,非常 昂贵 - 无论是时间还是成本。如果您有一个包含 100 万个条目的 table 并且期望扫描仅产生 5 个项目,那么您将需要支付读取 100 万个条目的费用才能得到 5 个。如果这些查询很常见,您可能需要重新考虑您的数据模型,以便典型的查询只需要读取一项 - 或者最多只查询一个分区 - 而不是完整的 table 扫描。