在Web应用程序中使用Dynamodb进行分页

时间:2013-11-04 09:02:02

标签: python django amazon-web-services boto amazon-dynamodb

我的数据库中有大约5000多个视频,我创建了一个页面http://mysite.com/videos来列出所有视频。现在我正在实施分页,因此每页只列出20个视频。 e.g。

  

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

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

我正在使用带有boto库的Python / Django。

3 个答案:

答案 0 :(得分:6)

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

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

你可以阅读:

ExclusiveStartKey 
     

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

     

ExclusiveStartKey的数据类型必须是String,Number或Binary。   不允许设置任何数据类型。

Type: String to AttributeValue object map

Required: No

Limit
     

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

Type: Number

Required: No

您不提供有关表格键的结构的任何信息。但是,该方法将查询表中与您的键匹配的元素(如果合适,则为范围键),限制设置为20。 在结果中,您将收到一个“LastEvaluatedKey”,您必须将其用于下一个查询,同样将限制设置为20.

答案 1 :(得分:2)

以下是一些选项:

  1. 您可以在应用程序启动时预加载所有视频对象,然后按照您希望的方式进行内存中分页。 5000多个对象应该不是什么大问题。
  2. 您可以获取第一页,然后异步获取其余内容(通过扫描),然后再次在内存中进行分页。
  3. 您可以创建一个索引表,为每个包含每个视频的id-s的页面存储一个条目,然后获取您要调用的页面的视频:  3.1按页面ID获取页面(简单获取操作)。这将包含应该在该页面上的视频ID列表  3.2通过执行多次获取操作从3.1获取所有视频
  4. 对于类似的用例,我们通过Javascript对象加载所有元数据,并从那里进行分页和排序,用户的最终结果很好(快速响应)。同样,我们正在使用获取第一页然后再获取整个内容的技巧(因为此时DynamoDB不支持游标)

答案 2 :(得分:0)

极限不是你的想法。这就是我的建议:

使用DynamoDBMapper发出

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

有效获取表格中的行数。

然后运行

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

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

使用

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

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