Java 在Google App Engine数据存储上执行大型查询

Java 在Google App Engine数据存储上执行大型查询,java,spring,google-app-engine,Java,Spring,Google App Engine,我正在使用Spring构建服务器。 我们有一个非常简单的查询(获取单一类型的所有实体),它在某个记录阈值(~1000000)之后无法运行 这是我尝试过的第一种方法(从Google文档中修改): 服务器在这两种情况下都引发了超时异常。 我做错什么了吗?感觉这应该是一个简单的操作。超时与请求执行的时间有关,而不是与实体的数量有关。如果在自动缩放的应用程序引擎实例上运行此查询,则有60秒的时间完成请求。数据存储查询的可用时间也有限制——如果结果数量很大,则需要使用游标 显而易见的解决方案不是将数百万条

我正在使用Spring构建服务器。 我们有一个非常简单的查询(获取单一类型的所有实体),它在某个记录阈值(~1000000)之后无法运行

这是我尝试过的第一种方法(从Google文档中修改):

服务器在这两种情况下都引发了超时异常。
我做错什么了吗?感觉这应该是一个简单的操作。

超时与请求执行的时间有关,而不是与实体的数量有关。如果在自动缩放的应用程序引擎实例上运行此查询,则有60秒的时间完成请求。数据存储查询的可用时间也有限制——如果结果数量很大,则需要使用游标


显而易见的解决方案不是将数百万条记录作为一个JSON对象返回,而是让客户机(或任何需要此数据的人)将它们放在可管理的块中,检索时间不到60秒。

我建议将结果分成小块进行检索……他已经在使用游标了。因此,解决方案是将光标字符串移动到请求参数和响应输出,以便客户机在下一个查询中提供。指出更多这一点并没有什么坏处……这听起来像是我所需要的——但是(忘了提及这一点)我如何以一种平静的方式做到这一点?我是否需要序列化我中断的点并将其发送到客户端?@johnyback cursor.towerbsafesting()显然是websafe。您可以将其添加到您的响应中。我通常为我的响应创建一个包装器类,其中包含以下信息:操作是否成功、是否还有更多条目、游标字符串是什么,当然还有数据本身。
PersistenceManager pm = persistenceManagerFactory.getPersistenceManager();
List<T> Qresults;
List<T> detachedList =  new LinkedList<T>();
try {
    Query query = pm.newQuery(cla);
    query.setRange(0, 200);
    List<T> results = (List<T>) query.execute();
    Cursor cursor = JDOCursorHelper.getCursor(results);
    String cursorString = cursor.toWebSafeString();
    do {
        cursor = Cursor.fromWebSafeString(cursorString);
        Map<String, Object> extensionMap = new HashMap<String, Object>();
        extensionMap.put(JDOCursorHelper.CURSOR_EXTENSION, cursor);
        query.setExtensions(extensionMap);
        query.setRange(0, 200);
        Qresults = (List<T>) query.execute();
        results.addAll(Qresults);
    } while(Qresults.size() == 200);

    for (T item : results) {
        detachedList.add(pm.detachCopy(item));
    }
    return detachedList;
} finally {
    pm.close();
}
JSONArray array = new JSONArray();
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Query q = new Query("MobileDevice");
FetchOptions options = FetchOptions.Builder.withChunkSize(1000);
PreparedQuery pq = datastore.prepare(q);

for (Entity result : pq.asIterable(options)) {
    array.put(new MobileDevice(result).toJSON());
}
return new transactionResult(array.toString());