DynamoDB Dynomite Result Paging
Important: These docs are for the outdated Jets 5 versions and below. For the latest Jets docs: docs.rubyonjets.com
A common way to iterate through posts is:
Post.each do |post|
# do something
end
Paging
If you need to access each page of results:
Post.each_page do |page|
page.each do |post|
# do something
end
end
You can specify conditions for the pages:
Post.where(category: "Cloud").each_page do |page|
page.each do |post|
# do something
end
end
If you need a page index, you can do this:
Post.each_page.with_index do |page, index|
page_number = index + 1
page.each do |post|
puts "page_number: #{page_number}"
# do something
end
end
Also, each_page
and pages
are aliases. Either works.
Raw Response Page
Sometimes you may need direct access to the raw response page from the AWS DynamoDB API. You can access it with raw_pages
or each_raw_page
. This allows you to grab the response.last_evaluated_key
and use it for additional requests.
Here’s a controller example that can help implement pagination for a web app.
class PostsController < ApplicationController
def index
primary_key = params[:next_token] ? JSON.parse(Base64.decode64(params[:next_token])) : nil
response, items = Post.start_at(primary_key).raw_pages.first
render json: {
items: items,
next_token: Base64.encode64(response.last_evaluated_key.to_json)
}
end
end
raw_pages
return a Lazy Enumerator that contains a 2-level array. It looks something like this:
[
[
#<struct Aws::DynamoDB::Types::ScanOutput items=[{"id"=>"post-1", "title"=>"post 1"},{"id"=>"post-2", "title"=>"post 2"},count=2,scanned_count=2,last_evaluated_key=nil> ],
[#<Post:0x00007f3ed7872180>, #<Post:0x00007f3ed7872068>]
],
[
#<struct Aws::DynamoDB::Types::ScanOutput items=[{"id"=>"post-4", "title"=>"post 4"},{"id"=>"post-4", "title"=>"post 4"},count=2,scanned_count=2,last_evaluated_key=nil> ],
[#<Post:0x00007f3ed7872900>, #<Post:0x00007f3ed7872ae0>]
],
...
]
The 1st element of each array is the RAW API response, the 2nd element of each array are the model objects. You can use the response.last_evaluated_key
to start the next page of posts.
Limit
Dynomite will paginate through all DynamoDB API response pages until no more pages are left. This ensures that all records or items are loaded. To limit the data, you can use limit
.
Post.limit(100).each do |post|
# do something
end
Dynomite will continue querying the API in paged responses until the limit is reached and there are no more records. More docs: Query Limit.