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

それは実際のコードですか?そのコードがその例外を生成する可能性は非常に低いようです。非アクティブな状態が10分間続くと、カーソルがタイムアウトします。そのようなタイトなループでは不可能に思えます。

datastore.createQuery(App.class).disableTimeout()...Morphiaでカーソルタイムアウトを無効にするために使用できます。フィールドに入力datastore.createQuery(App.class).fetchEmptyEntities()するだけの場合にも使用できます。@Id

fetch()また、そのようなforループでイテレータを使用するだけの場合は、明示的に呼び出す必要はありません。フェッチは、イテレータを変数に格納して複数の場所で使用する場合に必要ですが、単一のforループでは使用しません。

于 2011-02-12T08:29:55.290 に答える
1

非常に大きなクエリを繰り返し処理しているときに、同じ問題に遭遇しました。2011 年 3 月 21 日に報告された次の Morphia バグを見つけました。

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

問題 251: タイムアウトの有効化/無効化は、それが言うことの反対を行います

この問題は、バージョン 1.0 で修正されると言われています。新しい APIdisableCursorTimeout()は 1.00-SNAPHSHOT で公開されています。問題が解決するかどうかを確認するために、長いテストを実行しています。

于 2011-05-29T22:14:08.283 に答える
1

このスレッドでわかるように、MongoDB は一定時間後にカーソルを解放します。可能な解決策は、バッチ反復をエミュレートし、サイクルの最後にカーソルを更新することです。

于 2011-02-06T23:25:18.720 に答える