【问题标题】:App Engine Java: syntax for setting query limit and start offset.App Engine Java:用于设置查询限制和起始偏移量的语法。
【发布时间】:2011-07-29 01:31:01
【问题描述】:

我在 GAE 数据存储中有一个游戏列表,我想查询固定数量的游戏,从某个偏移量开始,即获取下一个 25 场游戏,从 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
//...

现在我需要扩展该查询以仅获取 25 个游戏,并且仅获取 ID 为“75”的条目之后的游戏。因此用户可以浏览打开的游戏,一次只能获取 25 个。 我知道 GAE 数据存储有很多示例,但这些示例大多都使用 Python,包括用于设置查询限制的示例代码。 我正在寻找一个有效的 Java 代码示例,但目前找不到。

【问题讨论】:

  • 使用不等查询过滤掉(我认为是)单个结果是一种资源浪费——SDK 必须执行两个查询来满足这一点。相反,从返回的结果集中过滤掉您不想要的单个结果。
  • 最多可以有 5 款游戏属于相关玩家。但实际上在查询数百个游戏时,1 或 5 没有区别,所以你明白了,我将把“!=”逻辑移出查询。

标签: java google-app-engine google-cloud-datastore


【解决方案1】:

听起来您想通过查询游标来促进分页。见:http://code.google.com/appengine/docs/java/datastore/queries.html#Query_Cursors

来自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>");
    }
}

【讨论】:

  • 嗯...看起来像我需要的,除了一个限制:您不能将游标用于使用 IN 或 != 过滤器运算符的查询。示例是使用另一个 API ,而不是 Persistence Manager,但这应该不是问题,我会试试这个,看看它是否适合我。
  • 谢谢,这比文档更清楚!为什么他们不能只提供该部分的代码示例?
  • 好的,但是为什么getOffset、getPrefetchSize、getChunkSize一旦设置为fetchOptions就返回null呢?
【解决方案2】:

感谢大家的帮助。光标是正确的答案。 问题是我几乎被 JDO 卡住了,不能使用 DatastoreService,所以我终于找到了这个链接: http://code.google.com/appengine/docs/java/datastore/jdo/queries.html#Query_Cursors

【讨论】:

    猜你喜欢
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    • 2018-11-07
    • 2019-06-06
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    相关资源
    最近更新 更多