2012-12-20 39 views
6

Her belgeyi belirli bir koleksiyonda almak için rmongodb kullanıyorum. Çalışıyor ama milyonlarca küçük belge ile çalışıyorum, potansiyel olarak 100 milyon dolar veya daha fazla. Web sitesinde yazar tarafından önerilen yöntem kullanıyorum: döngü ÇOK ÇOK yavaş ikenrmongodb kullanarak büyük sonuç kümesi işleme hızlandırır

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

Bu yüzlerce veya sonuçların binlerce çalışıyor cnub.org/rmongodb.ashx ama. Bunu hızlandırmanın bir yolu var mı? Belki çok işlem için bir fırsat? Herhangi bir öneri takdir edilecektir. Saatte 1M ortalama yaşıyorum ve bu hızda sadece veri çerçevesini oluşturmak için bir haftaya ihtiyacım var.

DÜZENLEME: while döngüsündeki daha fazla vektörün daha yavaş olduğunu fark ettim. Şimdi her vektör için ayrı ayrı döngü yapmaya çalışıyorum. Yine de bir hack gibi görünüyor, daha iyi bir yolu olmalı.

Düzen 2: Data.table ile biraz şans yaşıyorum. Onun hala çalışıyor ama 12M bitecek gibi görünüyor 4 saat içinde (bu benim geçerli test kümesidir), bu bir ilerleme ama çok ideal

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

Programcı değilim, infact Hiç kullanmadım ama neden tüm koleksiyon üzerinde yineleme yapmak yerine gerekli veri alt kümelerini seçip niçin doğrulama yapmak gerekiyor? Bu durumda, sadece bir yerine 6 imleçler sunucu tarafı gibi göndermek daha hızlı olacaktır. – Sammaye

+0

Huh? Tabii ki daha döngüdeki vektörler daha yavaş olur. Yapacak daha çok şey var. Yani daha uzun sürer. Yoksa doğrusal değil mi? Üzerinde döngü yaptığınız şeylerin farklı değerleri ile nasıl davranır? Veya 'daha fazla vektörler' ile yaş ve ad gibi daha fazla şey mi kastediyorsunuz? Anlaşılır değil. – Spacedman

+0

@Sammaye, her vektör için ayrı ayrı döngü yaparak kastettiğim şey bu. Dün geceyi denedim, bu döngüde bir sayaç koydum ve yeni öldü gibi görünüyor, birkaç saat sonra yazdırmayı durdurdu. Sadece duruşuyor. Yani bu yöntem yardımcı olmadı. – rjb101

cevap

3
Sen mongo.find.exhaust seçeneği denemek isteyebilirsiniz

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

Kullanım durumunuz için gerçekten çalışıyorsa, bu en kolay düzeltme olacaktır. Bununla birlikte, rmongodb sürücüsünün diğer sürücülerdeki bazı ekstra özellikleri kaçırdığı görülmektedir. Örneğin, JavaScript sürücüsünün bir Cursor.toArray yöntemi vardır. Tüm bul sonuçları doğrudan bir diziye döker. R sürücüsü mongo.bson.to.list işlevine sahiptir, ancak mongo.cursor.to.list muhtemelen ne istediğinizi. Muhtemelen tavsiye için sürücü geliştiricisine ping yapmaya değer.

Kaba bir çözüm, belgeleri her biri 100.000 belgenin verileri "parçaları" olan yeni bir koleksiyon oluşturmak olabilir. Daha sonra bunların her biri mongo.bson.to.list ile verimli bir şekilde okunabilir. Parçalanmış koleksiyon, mongo sunucusu MapReduce işlevselliği kullanılarak oluşturulabilir.

+0

'da bunu başarabilirseniz ilgilenirim mongo.find.exhaust'un hızı nasıl geliştireceği konusunda herhangi bir açıklama bulun. Nasıl çalıştığını biliyor musun? – user1176316

+0

Sınırlı anlayışım, tüm sorgu eşleşmelerinin bir defada getirilmesini zorlaştırmasıdır. Cursor.next dosyasından tekrarlanan çağrıların veri tabanına yükü önemli ise hızı iyileştirebilir. Bu kullanım durumunda gerçekten sadece% 3 yardımcı olma şansı verirdim, ancak denemeye değer basit bir değişiklik. En iyi referansım http://mongodb.github.com/node-mongodb-native/api-generated/collection.html#find – mjhm

1

Genel olarak bunu yapmanın daha hızlı bir yolunu bilmiyorum. Yabancı bir uygulamadan veri ithal ediyor ve yorumlanmış bir dil ile çalışıyorsunuz ve rmongodb'un koleksiyondaki belgelerin yapısını tahmin etmesinin bir yolu yok. Binlerce belgeyle uğraşırken süreç doğal olarak yavaştır.

+1

Teşekkürler Gerald. Dokümanlar mongo.find.exhaust'ta hafiftir, ayrıntılı olabilir misiniz? Bu seçeneği ekledim ve R çöktü. – rjb101

+0

sorunu i = i + 1 ile her seferinde eklenir. R'nin veri yapısını her defasında değiştirip sonra değiştirdiğine inanıyorum. Python'da olduğu gibi, yorumlanmış bir dil ile ilgisi yok. –

İlgili konular