0

我的数据库中有大约 5000 多个视频,并且我创建了一个页面http://mysite.com/videos来列出所有视频。现在我正在实施分页,以便每页仅列出 20 个视频。例如

http://mysite.com/videos?page=1显示前 20 个视频,http ://mysite.com/videos?page=2 显示后20 个视频。

我在选择实现分页的最佳方法时遇到问题。我想过每次执行新页面时都使用 table.scan() ,然后根据 Python 代码的一些逻辑只选择需要的。但这似乎相当昂贵。

我正在将 Python / Django 与 boto 库一起使用。

4

3 回答 3

6

在 Dynamo 中,您可以通过设置限制来执行查询。从文档中:

http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html

你可以阅读:

ExclusiveStartKey 

此操作将评估的第一项的主键。使用上一个操作中为 LastEvaluatedKey 返回的值。

ExclusiveStartKey 的数据类型必须是字符串、数字或二进制。不允许设置数据类型。

Type: String to AttributeValue object map

Required: No

Limit

要评估的最大项目数(不一定是匹配项目的数量)。如果 Amazon DynamoDB 在处理结果时处理的项目数达到限制,它会停止操作并返回到该点的匹配值,并返回一个 LastEvaluatedKey 以在后续操作中应用,以便您可以从离开的地方继续离开。此外,如果在 Amazon DynamoDB 达到此限制之前处理的数据集大小超过 1 MB,它会停止操作并返回达到限制的匹配值,并在后续操作中应用 LastEvaluatedKey 以继续操作。有关更多信息,请参阅 Amazon DynamoDB 开发人员指南中的查询和扫描。

Type: Number

Required: No

您没有提供有关表键的结构的任何信息。但是,方法是查询表中与您的键匹配的元素(如果合适,还有范围键),限制设置为 20。结果,您将收到一个“LastEvaluatedKey”,您必须在下一个使用查询,再次将限制设置为 20。

于 2013-11-27T11:22:22.127 回答
2

以下是一些选项:

  1. 您可以在应用程序启动时预加载所有视频对象,然后按照您想要的方式进行内存分页。5000 多个对象应该没什么大不了的。
  2. 您可以获取第一页,然后异步获取其余页面(通过扫描),然后再次在内存中进行分页。
  3. 您可以创建一个索引表,该表将存储每个页面的条目,其中包含每个视频的 id-s,然后获取您调用的页面的视频: 3.1 按页面 id 获取页面(简单的 get 操作)。这将包含应该在该页面上的视频 ID 列表 3.2 通过执行多重获取操作从 3.1 获取所有视频

对于类似的用例,我们通过 Javascript 对象加载所有元数据,并从那里进行分页和排序,用户的最终结果很好(快速且响应迅速)。同样,我们正在使用获取第一页然后再次获取整个内容的技巧(因为 DynamoDB 目前不支持游标)

于 2013-11-17T20:17:11.920 回答
1

极限不是你想的那样。这是我的建议:

使用 DynamoDBMapper 问题

numRows = mapper.count(<SomeClass>.class, scanExpression) 

有效地获取表中的行数。

然后运行一个

PaginatedScanList<FeedEntry> result = mapper.scan(<SomeClass>.class, scanExpression);

获取列表 - 这里的关键是 PaginatedScanList 是延迟加载的。注意不要对结果执行 .size() ,因为这将加载所有行。只需使用 .get() 仅加载您需要的行。

迭代 paginatedScanList 使用

offset = startPage * pageSize
ArrayList<SomeClass> list = new ArrayList<SomeClass>()
for (i = 0 ... pageSize) 
list.add(result.get( offset + i))

检查越界等。希望有帮助。

于 2014-06-23T18:02:40.093 回答