1

我正在尝试使用 Morphia 遍历我的 MongoDB 数据库中的所有行(“文档”?)。有时我会得到以下堆栈跟踪:

com.mongodb.MongoInternalException: can't do getmore
    at com.mongodb.DBApiLayer$Result._advance(DBApiLayer.java:378)
    at com.mongodb.DBApiLayer$Result.hasNext(DBApiLayer.java:356)
    at com.mongodb.DBCursor._hasNext(DBCursor.java:436)
    at com.mongodb.DBCursor.hasNext(DBCursor.java:456)
    at com.google.code.morphia.query.MorphiaIterator.hasNext(MorphiaIterator.java:40)
    at 

在 MongoDB 日志文件中,我看到以下内容:

$ grep "cursorid not found" output.log 
Sun Feb  6 12:14:35 [conn13] getMore: cursorid not found App 2079575931792020691
Sun Feb  6 12:44:17 [conn19] getMore: cursorid not found App 8364953818630631317
Sun Feb  6 13:08:42 [conn20] getMore: cursorid not found App 7142256996888968009

我的迭代代码非常简单:

    for (App app : datastore.createQuery(App.class).fetch())
    {
        log.info("app: " + app.getId());
        // do stuff with app
    }

吗啡虫?MongoDB 错误?我的虫子?

更新:

我也在我的 glassfish 日志中看到了这一点:

[#|2011-02-16T15:39:58.029+0000|WARNING|glassfish3.0.1|com.mongodb.TRACE|_ThreadID=28;_ThreadName=Thread-1;|The log message is null.
java.lang.NullPointerException
    at com.mongodb.DBApiLayer._cleanCursors(DBApiLayer.java:113)
    at com.mongodb.DBApiLayer$DBCleanerThread.run(DBApiLayer.java:494)
    at java.lang.Thread.run(Thread.java:662)
4

3 回答 3

1

正如您在此线程中看到的, MongoDB 在一定时间后释放游标。一个可能的解决方案可能是模拟批量迭代并在循环的和更新光标。

于 2011-02-06T23:25:18.720 回答
1

那是实际的代码吗?该代码似乎不太可能产生该异常。闲置 10 分钟后光标超时。像这样的紧密循环似乎是不可能的。

您可以使用datastore.createQuery(App.class).disableTimeout()...在 Morphia 中禁用光标超时。datastore.createQuery(App.class).fetchEmptyEntities()如果您只想@Id填写该字段,也可以使用。

fetch()此外,如果您只想在这样的 for 循环中使用迭代器,则无需显式调用;当您想将迭代器存储在一个变量中并在多个地方使用它而不是在单个 for 循环中时,才需要 fetch。

于 2011-02-12T08:29:55.290 回答
1

在迭代一个非常大的查询时遇到了同样的问题。我发现了这个 Morphia 错误,报告于 2011 年 3 月 21 日:

http://code.google.com/p/morphia/issues/detail?id=251

问题 251:启用/禁用超时与它所说的相反

该问题说它将在版本 1.0 中修复。新 APIdisableCursorTimeout()在 1.00-SNAPHSHOT 中公开。我正在进行长时间的测试,看看它是否能解决问题。

于 2011-05-29T22:14:08.283 回答