Justin
Justin

Reputation: 13

Google App Engine: How do you count query results given an offset?

I'm implementing pagination on sorted models and, as it stands, my queries are fetching way too much data. The way I display the links to the pages is similar to Google: the current page is highlighted and there is a surrounding "padding" of pages that you can navigate to. For instance, if there are 20 pages, the padding is 5, and you're on page 10, the page links would look like this:

... 5 6 7 8 9 [10] 11 12 13 14 15 ...

The thing is, I need to calculate the number of pages AFTER the current page in order to know how many page links past the current page should be shown. To do this, I sum the number of items I would need for the padding pages, plus the current page, plus one (to know whether to show the "..."), and then fetch these results. This results in a massive query of results that, ultimately, I only need a small subset of.

Google App Engine's api provides a count() function that returns the number of results a query fetches. However, it does not allow me to specify an offset.

How do I work around this problem?

I'm considering fetching the first item on the next page after the current page, then executing count() on another query that sorts on the values of that item, if that makes sense. Am I on the right track or am I missing something completely? I'm relatively new to app engine, so go easy! Thanks :)

UPDATE:

Thank you, Peter.

Cursors are indeed the appropriate approach to use. Here's an example for anyone looking to accomplish the same:

# For example, the following query has 27 results.
book_query = Book.all().filter("name_lowercase < ", "b" )
# Let's fetch 10 books starting at offset 0...
r = book_query.fetch(10, 0)
# This returns a cursor to the book after the last fetched result, index 10
c = book_query.cursor()

# Now let's count the number of results after our fetch, limit 100.
# To use cursors, the query must be exactly the same.
book_query2 = Book.all().filter("name_lowercase < ", "b" ).with_cursor(c) 
book_query2.count(100) # Returns 17

Upvotes: 1

Views: 605

Answers (1)

Peter
Peter

Reputation: 940

I haven't used them yet, but I believe Query Cursors are what you are looking for.

Upvotes: 1

Related Questions