2014-06-13 34 views
23

Aşağıdaki kod ile bir Mongo veritabanında mevcut bazı kimlikleri getirmek çalışıyorum geçerli değil: Kısa bir sonrapymongo.errors.CursorNotFound: İmleç id '...' sunucuya

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'] 

Ancak

pymongo.errors.CursorNotFound: cursor id '...' not valid at server.

o sorunu ifade eder bu article bulundu: süre, bu hatayı almaya değilim. Yine de, hangi çözümü alacağımı açık değil. find().batch_size(30) kullanmak mümkün mü? Yukarıdaki komut tam olarak ne yapar? Tüm veritabanı kimliklerini batch_size kullanarak alabilir miyim?

cevap

44

İmleç sunucuda zaman aşımına uğradığından (10 dakika işlem yapılmadığında) bu hatayı alıyorsunuz. pymongo belgelerine

: Eğer bir koleksiyon sorgular collection.find yöntem çağırır ve belgelere bir imleç döndürür

Cursors in MongoDB can timeout on the server if they’ve been open for a long time without any operations being performed on them. This can lead to an CursorNotFound exception being raised when attempting to iterate the cursor.

. Belgeleri almak için imleci tekrarlarsınız. İmleç üzerinde yinelediğinizde, sürücü aslında daha fazla veriyi sunucudan almak için MongoDB sunucusuna istekte bulunuyor. Her istekte döndürülen veri miktarı batch_size() yöntemiyle belirlenir. documentation itibaren

: daha düşük bir değere batch_size ayarlanması

Limits the number of documents returned in one batch. Each batch requires a round trip to the server. It can be adjusted to optimize performance and limit data transfer.

zaman aşımı hataları hataları ile yardımcı olacaktır, ancak bu kadar MongoDB sunucusuna erişmek alacağız sayısını artıracak tüm belgeleri al.

varsayılan parti boyutu:

evrensel "doğru" parti boyutu vardır

For most queries, the first batch returns 101 documents or just enough documents to exceed 1 megabyte. Batch size will not exceed the maximum BSON document size (16 MB).

. Farklı değerler ile test etmeli ve kullanım durumunuz için uygun değerin ne olduğunu görmelisiniz, yani 10 dakikalık bir pencerede kaç doküman işleyebilirsiniz.

Son çare, timeout=False'u ayarlamanız olacaktır. Ancak verileri işledikten sonra imlecin kapalı olduğundan emin olmanız gerekir. Böyle

+0

Batch_size'yi 50 olarak tanımladım. Ancak aynı hatayı aldım pymongo.errors.CursorNotFound: imleç kimliği '' hizmet biriminde geçerli değil. Batch_size ayarlamam gereken doğru değer nedir? –

+0

@snakeplissken - benim yanıt güncellendi –

+0

Zaman aşımı kullanımı ile nasıl emin olabilirim. İmleç kapalı olduğundan nasıl emin olabilirim? –

26

Kullanım no_cursor_timeout=True: Sen zaman aşımına (yaklaşık 10 dakika) böylece imleç artık yok daha imleci kullanıyorlardı

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 
0

.

col.find({}).batch_size(10) 

veya

col.find(timeout=False) false zaman aşımı ayarlamak ve unutma (örneğin Pymongo ile)

:

Sorunu gidermek için batch_size düşük bir değere seçmeliyim sonunda imleci kapatmak için

+0

için zaman aşımına uğradı @Christian P cevap, daha ayrıntılı – hisi