i4niac
i4niac

Reputation: 23

App Engine Java: syntax for setting query limit and start offset.

I have a list of games in GAE datastore and I want to query fixed number of them, starting from a certain offset, i.e. get next 25 games starting form entry with id "75".

PersistenceManager pm = PMF.get().getPersistenceManager(); // from Google examples
Query query = pm.newQuery(Game.class); // objects of class Game are stored in datastore
query.setOrdering("creationDate asc");
/* querying for open games, not created by this player */
query.setFilter("state == Game.STATE_OPEN && serverPlayer.id != :playerId");
String playerId = "my-player-id";
List<Game> games = query.execute(playerId); // if there's lots of games, returned list has more entries, than user needs to see at a time
//...

Now I need to extend that query to fetch only 25 games and only games following entry with id "75". So the user can browse for open games, fetching only 25 of them at a time. I know there's lots of examples for GAE datastore, but those all are mostly in Python, including sample code for setting limit on the query. I am looking for a working Java code sample and couldn't find one so far.

Upvotes: 2

Views: 1741

Answers (2)

i4niac
i4niac

Reputation: 1

Thanks everyone for help. The cursors was the right answer. The thing is that I am pretty much stuck with JDO and can't use DatastoreService, so I finally found this link: http://code.google.com/appengine/docs/java/datastore/jdo/queries.html#Query_Cursors

Upvotes: 0

cheeken
cheeken

Reputation: 34675

It sounds like you want to facilitate paging via Query Cursors. See: http://code.google.com/appengine/docs/java/datastore/queries.html#Query_Cursors

From the Google doc:

public class ListPeopleServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
          throws ServletException, IOException {

        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
        Query q = new Query("Person");
        PreparedQuery pq = datastore.prepare(q);
        int pageSize = 15;

        resp.setContentType("text/html");
        resp.getWriter().println("<ul>");

        FetchOptions fetchOptions = FetchOptions.Builder.withLimit(pageSize);
        String startCursor = req.getParameter("cursor");

        // If this servlet is passed a cursor parameter, let's use it
        if (startCursor != null) {
            fetchOptions.startCursor(Cursor.fromWebSafeString(startCursor));
        }

        QueryResultList<Entity> results = pq.asQueryResultList(fetchOptions);
        for (Entity entity : results) {
            resp.getWriter().println("<li>" + entity.getProperty("name") + "</li>");
        }
        resp.getWriter().println("</ul>");

        String cursor = results.getCursor().toWebSafeString();

        // Assuming this servlet lives at '/people'
        resp.getWriter().println(
            "<a href='/people?cursor=" + cursor + "'>Next page</a>");
    }
}

Upvotes: 4

Related Questions