2014-06-13 14 views
23

Tôi cố gắng để lấy một số id mà tồn tại trong một cơ sở dữ liệu Mongo với đoạn mã sau:pymongo.errors.CursorNotFound: id con trỏ '...' không hợp lệ tại máy chủ

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

Tuy nhiên, sau một thời gian ngắn thời gian, tôi nhận được lỗi này:

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

tôi thấy article này trong đó đề cập đến vấn đề đó. Tuy nhiên nó không phải là rõ ràng với tôi mà giải pháp để có. Có thể sử dụng find().batch_size(30) không? Chính xác thì lệnh trên làm gì? Tôi có thể lấy tất cả các id cơ sở dữ liệu bằng cách sử dụng batch_size không?

Trả lời

44

Bạn nhận được lỗi này vì con trỏ đang hết thời gian trên máy chủ (sau 10 phút không hoạt động).

Từ các tài liệu pymongo:

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.

Khi bạn gọi phương pháp collection.find nó truy vấn một bộ sưu tập và nó trả về một con trỏ đến các tài liệu. Để có được các tài liệu bạn lặp lại con trỏ. Khi bạn lặp qua con trỏ, trình điều khiển thực sự đang thực hiện các yêu cầu tới máy chủ MongoDB để tìm nạp thêm dữ liệu từ máy chủ. Lượng dữ liệu trả về trong mỗi yêu cầu được đặt theo phương pháp batch_size().

Từ documentation:

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.

Thiết lập batch_size đến một giá trị thấp hơn sẽ giúp bạn với các lỗi lỗi timeout, nhưng nó sẽ làm tăng số lần bạn sẽ có được truy cập vào máy chủ MongoDB để nhận tất cả các tài liệu.

Lô mặc định kích thước:

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).

Không có phổ quát "đúng" kích thước hàng loạt. Bạn nên thử nghiệm với các giá trị khác nhau và xem giá trị thích hợp cho trường hợp sử dụng của bạn là gì, nghĩa là bạn có thể xử lý bao nhiêu tài liệu trong cửa sổ 10 phút.

Phương sách cuối cùng sẽ là bạn đặt timeout=False. Nhưng bạn cần phải chắc chắn rằng con trỏ được đóng lại sau khi bạn xử lý xong dữ liệu.

+0

Tôi đã xác định batch_size là 50. Tuy nhiên, tôi nhận được lỗi giống pymongo.errors.CursorNotFound: id con trỏ '' không hợp lệ tại serv er. Giá trị đúng tôi phải đặt batch_size là gì? –

+0

@snakeplissken - cập nhật câu trả lời của tôi –

+0

Làm thế nào tôi có thể chắc chắn với việc sử dụng thời gian chờ. Làm thế nào tôi có thể chắc chắn rằng con trỏ được đóng lại? –

26

Sử dụng no_cursor_timeout=True như thế này:

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

Bạn đang sử dụng con trỏ hơn lần ra (khoảng 10 phút) để con không còn tồn tại.

bạn nên chọn một giá trị thấp của batch_size để khắc phục vấn đề:

(với Pymongo ví dụ)

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

hoặc

đặt thời gian chờ là false col.find(timeout=False) và đừng quên để đóng con trỏ ở cuối.

+0

xem câu trả lời @Christian P, chi tiết hơn – hisi

Các vấn đề liên quan