我正在使用rmongodb来获取特定集合中的每个文档。它可以使用,但我正在使用数百万个的小型文档,可能是100m或更多。我正在使用作者在网站上建议的方法:cnub.org/rmongodb.ashx
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))
这可以很好地适用于数百或数千个结果,但是尽管循环非常慢。有什么方法可以加快这一目标吗?也许是多处理的机会?任何建议,将不胜感激。我的平均每小时为1m,以此速度,我需要一周才能构建数据框架。
编辑:我注意到,在循环中越慢的向量速度较慢。我现在尝试为每个向量分开循环。
似乎仍然有一个更好的方法。编辑2:我对Data.Table有些运气。它仍在运行,但看起来它将在4小时内完成12m(这是我当前的测试集),这是进步,但远非理想
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"))
}
您可能想尝试mongo.find.exhaust
选项
cursor <- mongo.find(mongo, query, options=[mongo.find.exhaust])
如果实际上适合您的用例,这将是最简单的修复。
但是,RMONGODB驱动程序似乎缺少其他驱动程序上可用的一些额外功能。例如,JavaScript驱动程序具有Cursor.toArray
方法。将所有查找结果直接转储到数组中。R驱动程序具有mongo.bson.to.list
功能,但是您想要的mongo.cursor.to.list
可能是您想要的。可能值得为驾驶员开发人员提供建议。
可能是创建一个新的集合,其文档是每个原始文档的100000个数据"块"。然后,所有这些都可以用mongo.bson.to.list
有效地读取。可以使用Mongo Server MapReduce功能构建块的集合。
我不知道以一般方式做到这一点。您正在从外国应用程序中导入数据并使用解释的语言,并且RMONGODB无法预测集合中文档的结构。当您处理数千个文档时,该过程固有地慢。