42

私はこのループを反復しようとしています:

for doc in coll.find()

100,000 件以上のレコードで次のエラーが表示されます。

File "build\bdist.win32\egg\pymongo\cursor.py", line 703, in next
File "build\bdist.win32\egg\pymongo\cursor.py", line 679, in _refresh
File "build\bdist.win32\egg\pymongo\cursor.py", line 628, in __send_message
File "build\bdist.win32\egg\pymongo\helpers.py", line 95, in _unpack_response
pymongo.errors.OperationFailure: cursor id '1236484850793' not valid at server

このエラーはどういう意味ですか?

4

5 に答える 5

38

サーバー上でカーソルがタイムアウトした可能性があります。これが問題であるかどうかを確認するには、timeout=False`を設定してみてください。

for doc in coll.find(timeout=False)

http://api.mongodb.org/python/1.6/api/pymongo/collection.html#pymongo.collection.Collection.findを参照してください

タイムアウトの問題であった場合、考えられる解決策の1つは、batch_size(他の回答)を設定することです。

于 2012-04-24T13:05:00.380 に答える
36
  • を設定することtimeout=Falseは危険であり、絶対に使用しないでください。カーソルへの接続が無制限に開いたままになる可能性があり、システムのパフォーマンスに影響を与える可能性があります。ドキュメントは、カーソルを手動で閉じる必要があることを具体的に言及しています。
  • を小さい値に設定しbatch_sizeても機能しますが、必要以上に頻繁に DB にアクセスする必要があるため、大きな遅延の問題が発生します。
    例:
    小さなバッチの 500 万ドキュメントでは、デフォルトの batch_size が数分で返すのと同じデータを取得するのに数時間かかります。

私のソリューションでは、カーソルで並べ替えを使用することが必須です:

done = False
skip = 0
while not done:
    cursor = coll.find()
    cursor.sort( indexed_parameter ) # recommended to use time or other sequential parameter.
    cursor.skip( skip )
    try:
        for doc in cursor:
            skip += 1
            do_something()
        done = True
    except pymongo.errors.OperationFailure, e:
        msg = e.message
        if not (msg.startswith("cursor id") and msg.endswith("not valid at server")):
            raise
于 2013-10-01T13:34:15.507 に答える
26

設定timeout=Falseは非常に悪い習慣です。カーソル ID のタイムアウト例外を取り除くより良い方法は、ループが 10 分以内に処理できるドキュメントの数を見積もり、控えめなバッチ サイズを考え出すことです。このように、MongoDB クライアント (この場合は PyMongo) は、前のバッチのドキュメントが使い果たされるたびに、時々サーバーにクエリを実行する必要があります。これにより、サーバー上でカーソルがアクティブなままになり、10 分間のタイムアウト保護が適用されます。

カーソルのバッチ サイズを設定する方法は次のとおりです。

for doc in coll.find().batch_size(30):
    do_time_consuming_things()
于 2013-07-14T21:36:50.757 に答える
-1

以下を使用して評価を強制することもできます。

for doc in list(coll.find())
于 2015-11-27T18:37:42.777 に答える