web-dev-qa-db-ja.com

pymongo.errors.CursorNotFound:カーソルID '...'はサーバーで無効です

次のコードを使用して、mongoデータベースに存在するIDを取得しようとしています。

_client = MongoClient('xx.xx.xx.xx', xxx)
db = client.test_database
db = client['...']
collection = db.test_collection
collection = db["..."]


for cursor in collection.find({ "$and" : [{ "followers" : { "$gt" : 2000 } }, { "followers" : { "$lt" : 3000 } }, { "list_followers" : { "$exists" : False } }] }): 
    print cursor['screenname']
    print cursor['_id']['uid']
    id = cursor['_id']['uid']
_

ただし、しばらくすると、次のエラーが表示されます。

pymongo.errors.CursorNotFound:カーソルID '...'はサーバーで無効です。

私はこれを見つけました 記事 これはその問題を指します。それにもかかわらず、どの解決策を取るべきかは明確ではありません。 find().batch_size(30)を使用できますか?上記のコマンドは正確に何をしますか? _batch_size_を使用してすべてのデータベースIDを取得できますか?

48
snake plissken

サーバーでカーソルがタイムアウトしているため(この状態は10分間使用されていないため)このエラーが発生しています。

Pymongoドキュメントから:

MongoDBのカーソルは、操作が実行されずに長時間開いていると、サーバー上でタイムアウトする可能性があります。これにより、カーソルを反復しようとしたときにCursorNotFound例外が発生する可能性があります。

_collection.find_メソッドを呼び出すと、コレクションを照会し、ドキュメントにカーソルを返します。ドキュメントを取得するには、カーソルを繰り返します。カーソルを反復処理すると、ドライバーは実際にMongoDBサーバーにリクエストを行って、サーバーからより多くのデータを取得します。各リクエストで返されるデータの量は、batch_size()メソッドによって設定されます。

ドキュメント から:

1つのバッチで返されるドキュメントの数を制限します。各バッチには、サーバーへの往復が必要です。パフォーマンスを最適化し、データ転送を制限するために調整できます。

Batch_sizeを低い値に設定すると、タイムアウトエラーとエラーの解決に役立ちますが、MongoDBサーバーにアクセスしてすべてのドキュメントを取得する回数が増えます。

デフォルトのバッチサイズ:

ほとんどのクエリでは、最初のバッチは101個のドキュメント、または1メガバイトを超えるだけのドキュメントを返します。バッチサイズは、BSONドキュメントの最大サイズ(16 MB)を超えません。

普遍的な「正しい」バッチサイズはありません。さまざまな値でテストし、ユースケースに適した値、つまり10分間で処理できるドキュメントの数を確認する必要があります。

最後の手段は、_no_cursor_timeout=True_を設定することです。ただし、データの処理が終了したら、カーソルが閉じていることを確認する必要があります。

例:

_cursor = collection.find({"x": 1}, no_cursor_timeout=True)
for doc in cursor:
    # do something with doc
cursor.close()
_
73
Christian P

つかいます no_cursor_timeout=True このような:

cursor=db.images.find({}, {'id':1, 'image_path':1, '_id':0}, no_cursor_timeout=True)
for i in cursor:
    # .....
    # .....
cursor.close() # use this or cursor keeps waiting so ur resources are used up
45
Mani

カーソルをタイムアウト(約10分)以上使用していたため、カーソルは存在しません。

問題を修正するには、batch_sizeの低い値を選択する必要があります。

(たとえば、Pymongoを使用)

_col.find({}).batch_size(10)
_

または

タイムアウトをfalse col.find(timeout=False)に設定し、最後にカーソルを閉じることを忘れないでください。

4
HISI