Morphia/MongoDB:不能做 getmore
我正在尝试使用 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
}
Morphia bug? 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)
I'm trying to iterate over all rows ("documents"?) in my MongoDB database using Morphia. Occasionally I get the following stacktrace:
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
In the MongoDB log file I see the following:
$ 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
My code for iterating is pretty straightforward:
for (App app : datastore.createQuery(App.class).fetch())
{
log.info("app: " + app.getId());
// do stuff with app
}
Morphia bug? MongoDB bug? My bug?
Update:
I'm also seeing this in my glassfish logs:
[#|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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在迭代一个非常大的查询时遇到了同样的问题。我发现了这个 Morphia bug,报告于 2011 年 3 月 21 日:
http:// code.google.com/p/morphia/issues/detail?id=251
该问题表示它将在 1.0 版中修复。新的 API
disableCursorTimeout()
在 1.00-SNAPHSHOT 中公开。我正在运行一个长时间测试,看看它是否可以解决问题。Just ran into the same problem while iterating through a very large Query. I found this Morphia bug, reported on Mar 21, 2011:
http://code.google.com/p/morphia/issues/detail?id=251
The issue says it will be fixed in version 1.0. The new API
disableCursorTimeout()
is exposed in 1.00-SNAPHSHOT. I'm running a long test to see if it fixes the problem.正如您在此帖子中看到的MongoDB 在一定时间后释放游标。一种可能的解决方案可能是模拟批量迭代并在循环结束时更新光标。
As you can see in this thread MongoDB releases cursor after a certain amount of time. A possible solution might be to do emulate batch iteration and renew the cursor at the and of the cycle.
这是实际的代码吗?该代码似乎不太可能产生该异常。光标在 10 分钟不活动后超时。有了这样一个紧密的循环,这似乎是不可能的。
您可以使用
datastore.createQuery(App.class).disableTimeout()...
禁用 Morphia 中的光标超时。如果您只想填写@Id
字段,也可以使用datastore.createQuery(App.class).fetchEmptyEntities()
。此外,无需显式调用
fetch()
如果您只想在类似的 for 循环中使用迭代器;当您想要将迭代器存储在变量中并在多个位置使用它而不是在单个 for 循环中时,才需要 fetch。Is that the actual code? It seems very unlikely that that code would produce that exception. Cursors timeout after 10 minutes of inactivity. With a tight loop like that it seems impossible.
You can use
datastore.createQuery(App.class).disableTimeout()...
to disable the cursor timeout in Morphia. You can also usedatastore.createQuery(App.class).fetchEmptyEntities()
if you just want the@Id
field filled in.Also, there is no need to explicitly call
fetch()
if you just want to use the iterator in a for-loop like that; fetch is just needed when you want to store the iterator in a variable and use it in multiple places, but not in a single for-loop.