2015-08-06 3 views
4

Я пытался импортировать данные из MongoDB в г с помощью:долгое время импортировать данные с помощью mongo.find.all (rmongodb)

mongo.find.all(mongo, namespace, query=query, 
fields= list('_id'= 0, 'entityEventName'= 1, context= 1, 'startTime'=1), data.frame= T) 

Команда работает найти для небольших наборов данных, но я хочу, чтобы импортировать 1000000 документы.

Используя system.time и добавляя предел = X к команде, я измерять время как функции данных для импорта:

system.time(mongo.find.all(mongo, namespace, query=query , 
fields= list('_id'= 0, 'entityEventName'= 1, context= 1, 'startTime'=1), 
limit= 10000, data.frame= T)) 

Результаты:

Data Size Time 
1   0.02 
100   0.29 
1000  2.51 
5000  16.47 
10000  20.41 
50000  193.36 
100000  743.74 
200000  2828.33 

После нанесения на график данные, которые я считаю, что: Import Time = F (данных^2)

Time = -138,3643 + 0,0067807 * Размер данных + 6,77 (Размер-45762,6 данных) 3e-8 *^2

R^2 = 0,999997

  1. Я правильно?
  2. Есть ли более быстрая команда?

Спасибо!

ответ

3

lm это круто, но я думаю, что если вы попытаетесь добавить мощность 3,4,5, ... функции, вы также будете получать большие R^2 =) вы overfit =)

One из известных недостатков R заключается в том, что вы не можете эффективно добавлять элементы в vector (или list). Добавляющий элемент запускает копию всего объекта. И здесь вы можете увидеть производный этого эффекта. Обычно, когда вы извлекаете данные из mongodb, вы заранее не знаете размер результата. Вы повторяете курсор и увеличиваете итоговый список. В старых версиях эта процедура была невероятно медленной из-за описанного выше поведения R. После this pull производительность становится намного лучше. Трюк с environment s помогает много, но он все еще не так быстро, как предварительно выделенный список.

Но можем ли мы потенциально лучше? Да.

1) Просто позвольте пользователю указать размер результата и список предварительного распределения. И сделайте это автоматически, если limit= передано в mongo.find.all. I filled issue для этого улучшения.
2) Построить результат в C код.

Если знать размер ваших данных заранее вы можете:

cursor <- mongo.find(mongo, namespace, query=query, fields= list('_id'= 0, 'entityEventName'= 1, context= 1, 'startTime'=1)) 
result_lst <- vector('list', NUMBER_OF_RECORDS) 
i <- 1 
while (mongo.cursor.next(cursor)) { 
    result_lst[[i]] <- mongo.bson.to.list(mongo.cursor.value(cursor)) 
    i <- i + 1 
} 
result_dt <- data.table::rbindlist(result_lst) 
+0

Thx Dmitriy! В большинстве случаев я хочу извлечь все документы в своей коллекции, чтобы узнать размер результата (используя «mongo.count»). Но я не понимаю, что это: cursor <- mongo.find (...)? Кроме того, я считаю, что можно использовать mapply вместо цикла - время вычисления будет значительно короче :) –

+0

см. Обновленный код. 'mapply' не поможет, потому что вам нужно перебирать курсор. Если вы не понимаете, как это работает, обратитесь к руководству MongoDB: http://docs.mongodb.org/manual/core/cursors/ –

+0

в цикле 'while' не должно быть' result_lst [[i]] '? – tospig