I have a very large dataset that i am exporting using a batch process to keep the page from timing out. The whole process can take over an hour, and i'm using drupal batch which basically reloads the page with a status on how far the process has completed. Each page request essentially runs the query again which includes a sort which takes a while. Then it exports the data to a temp file. The next page load runs the full mongo query, sorts, skips the entries already exported, and exports more to the temp file. The problem is that each page load makes mongo rerun the entire query and sort. I'd like to be able to have the next batch page just pick up the same cursor where it left off and continue to pull the next set of results.
2 回答
MongoDB 手册条目cursor.skip()
给出了一些建议:
考虑对这些类型的任务使用基于范围的分页。也就是说,查询一系列对象,使用应用程序中的逻辑来确定分页而不是数据库本身。如果您不需要轻松跳转到特定页面,这种方法具有更好的索引利用率。
例如,如果您的夜间批处理运行在过去 24 小时内累积的数据上,也许您可以运行基于日期范围的查询(可能一天中每小时一次)并以这种方式处理您的数据。我假设您的数据包含每个文档的某种可用时间戳,但您明白了。
尽管游标存在于服务器上并且仅在大约 10 分钟无活动后才超时,但 PHP 驱动程序不支持在请求之间保持游标。
在每个请求结束时,驱动程序将终止在该请求期间创建的所有尚未耗尽的游标。当所有对 MongoCursor 对象的引用都被删除时也会发生这种情况(例如 $cursor = null)。
这样做是因为不幸的是,应用程序不遍历整个游标是相当普遍的,而且我们不希望将未使用的游标留在服务器上,因为它可能会影响性能。
对于您的具体情况,最好的方法work around this problem
是改进您的索引,以便更快地加载光标。您可能还想只选择数据的某个子集,这样您就有一个可以请求数据的固定点。
比如说,对于报告,您的第一个请求可能会要求提供从凌晨 1 点到凌晨 2 点的所有数据。然后,您的下一个请求要求提供从凌晨 2 点到凌晨 3 点的所有数据,依此类推,就像 Saftschleck 解释的那样。
您可能还想研究旨在进行“在线报告”的聚合框架:http: //docs.mongodb.org/manual/aggregation/