2012-12-20 10 views
6

Tôi đang sử dụng rmongodb để lấy mọi tài liệu trong một bộ sưu tập cụ thể. Nó hoạt động nhưng tôi đang làm việc với hàng triệu tài liệu nhỏ, có khả năng 100M hoặc nhiều hơn. Tôi đang sử dụng phương pháp được đề xuất bởi các tác giả trên trang web: cnub.org/rmongodb.ashxtăng tốc độ xử lý tập hợp kết quả lớn bằng rmongodb

count <- mongo.count(mongo, ns, query) 
cursor <- mongo.find(mongo, query) 
name <- vector("character", count) 
age <- vector("numeric", count) 
i <- 1 
while (mongo.cursor.next(cursor)) { 
    b <- mongo.cursor.value(cursor) 
    name[i] <- mongo.bson.value(b, "name") 
    age[i] <- mongo.bson.value(b, "age") 
    i <- i + 1 
} 
df <- as.data.frame(list(name=name, age=age)) 

này hoạt động tốt cho hàng trăm hoặc hàng ngàn kết quả nhưng điều đó trong khi vòng lặp là rất rất chậm. Có cách nào để tăng tốc độ này không? Có lẽ một cơ hội để xử lý đa? Mọi lơi đê nghị đêu nên được đanh gia cao. Tôi trung bình 1M mỗi giờ và với tốc độ này, tôi cần một tuần để xây dựng khung dữ liệu.

EDIT: Tôi nhận thấy rằng nhiều vectơ trong vòng lặp while chậm hơn. Bây giờ tôi đang cố gắng lặp lại riêng biệt cho mỗi véc tơ. Tuy nhiên có vẻ như một hack, phải có một cách tốt hơn.

Chỉnh sửa 2: Tôi đang gặp may mắn với data.table. Nó vẫn chạy nhưng có vẻ như nó sẽ kết thúc 12M (đây là hiện tại tập kiểm tra của tôi) trong 4 giờ, đó là sự tiến bộ nhưng xa lý tưởng

dt <- data.table(uri=rep("NA",count), 
       time=rep(0,count), 
       action=rep("NA",count), 
       bytes=rep(0,count), 
       dur=rep(0,count)) 

while (mongo.cursor.next(cursor)) { 
    b <- mongo.cursor.value(cursor) 
    set(dt, i, 1L, mongo.bson.value(b, "cache")) 
    set(dt, i, 2L, mongo.bson.value(b, "path")) 
    set(dt, i, 3L, mongo.bson.value(b, "time")) 
    set(dt, i, 4L, mongo.bson.value(b, "bytes")) 
    set(dt, i, 5L, mongo.bson.value(b, "elaps")) 

}

+0

Tôi không có lập trình viên r, infact Tôi chưa bao giờ sử dụng nó, tuy nhiên tại sao bạn không chọn các tập con dữ liệu bạn cần thay vì chỉ lặp lại toàn bộ bộ sưu tập và sau đó thực hiện xác nhận yêu cầu? Trong trường hợp này nó sẽ dễ dàng gửi nhanh hơn như 6 con trỏ phía máy chủ thay vì chỉ một. – Sammaye

+0

Huh? Tất nhiên các vectơ nhiều hơn trong vòng lặp while chậm hơn. Còn nhiều việc phải làm. Vì vậy, phải mất nhiều thời gian hơn. Hay nó không tuyến tính? Nó hoạt động như thế nào với các giá trị khác nhau về số thứ bạn đang lặp lại? Hoặc bằng 'nhiều vectơ' hơn bạn có nghĩa là nhiều thứ hơn như tuổi tác và tên? Không rõ ràng. – Spacedman

+0

@Sammaye, thats chính xác những gì tôi có nghĩa là bằng cách lặp riêng cho mỗi vector. Tôi đã thử đêm qua, đặt một cái đếm trong vòng lặp đó và dường như đã chết, nó dừng in sau vài giờ. Sự lúng túng chỉ là treo. Vì vậy, phương pháp này đã không giúp đỡ. – rjb101

Trả lời

3

Bạn có thể muốn thử các tùy chọn mongo.find.exhaust

cursor <- mongo.find(mongo, query, options=[mongo.find.exhaust]) 

Đây sẽ là sửa chữa dễ nhất nếu thực sự hoạt động cho trường hợp sử dụng của bạn.

Tuy nhiên trình điều khiển rmongodb dường như thiếu một số tính năng bổ sung khả dụng trên các trình điều khiển khác. Ví dụ trình điều khiển JavaScript có phương thức Cursor.toArray. Mà trực tiếp bãi tất cả các kết quả tìm thấy một mảng. Trình điều khiển R có chức năng mongo.bson.to.list, nhưng mongo.cursor.to.list có lẽ là những gì bạn muốn. Nó có thể đáng giá ping nhà phát triển trình điều khiển để được tư vấn.

Giải pháp hacky có thể là tạo bộ sưu tập mới có tài liệu là "khối" dữ liệu là 100000 tài liệu gốc. Sau đó, mỗi trong số này có thể được đọc hiệu quả với mongo.bson.to.list. Bộ sưu tập chunked có thể được xây dựng bằng chức năng MapReduce của máy chủ mongo.

+0

Tôi không thể tìm bất kỳ lời giải thích nào về cách mongo.find.exhaust sẽ cải thiện tốc độ. Bạn có biết nó hoạt động như thế nào không? – user1176316

+0

Sự hiểu biết hạn chế của tôi là nó buộc truy xuất tất cả các kết quả truy vấn cùng một lúc. Nó có thể cải thiện tốc độ nếu chi phí của các cuộc gọi lặp đi lặp lại từ con trỏ.next đến cơ sở dữ liệu là đáng kể. Tôi sẽ chỉ cho nó 3% cơ hội thực sự giúp đỡ trong trường hợp sử dụng này, nhưng đó là một thay đổi đơn giản đáng để thử. Tài liệu tham khảo tốt nhất của tôi là http://mongodb.github.com/node-mongodb-native/api-generated/collection.html#find – mjhm

1

Tôi biết không có cách nào nhanh hơn để thực hiện việc này theo cách thông thường. Bạn đang nhập dữ liệu từ một ứng dụng nước ngoài và làm việc với một ngôn ngữ thông dịch và không có cách nào rmongodb có thể dự đoán cấu trúc của các tài liệu trong bộ sưu tập. Quá trình này vốn đã chậm khi bạn xử lý hàng nghìn tài liệu.

+1

Cảm ơn Gerald. Các tài liệu là loại ánh sáng trên mongo.find.exhaust, bạn có thể xây dựng? Tôi đã thêm tùy chọn này và R bị lỗi. – rjb101

+0

vấn đề là trong nối thêm mỗi lần xung quanh với i = i + 1. Tôi tin rằng R là sao chép cấu trúc dữ liệu mỗi lần sau đó thay thế nó, do đó, nó càng lớn thì càng tệ. Nó không liên quan gì đến một ngôn ngữ thông dịch, như trong Python, đây là đơn đặt hàng của cường độ nhanh hơn. –