rjb*_*101 6 r bigdata mongodb dataframe rmongodb
我正在使用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))
Run Code Online (Sandbox Code Playgroud)
这适用于数百或数千个结果但是循环非常非常慢.有什么方法可以加快速度吗?也许是多处理的机会?任何建议,将不胜感激.我平均每小时1M,按照这个速度,我只需要一周时间来构建数据框.
编辑:我注意到while循环中的矢量越多,它就越慢.我现在正试图为每个向量分别循环.虽然看起来仍然像黑客,但必须有更好的方法.
编辑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"))
Run Code Online (Sandbox Code Playgroud)
}
您可能想尝试该mongo.find.exhaust选项
cursor <- mongo.find(mongo, query, options=[mongo.find.exhaust])
Run Code Online (Sandbox Code Playgroud)
如果确实适用于您的用例,这将是最简单的修复。
然而,rmongdb 驱动程序似乎缺少其他驱动程序上可用的一些额外功能。例如,JavaScript 驱动程序有一个Cursor.toArray方法。它直接将所有查找结果转储到数组中。R 驱动程序有一个mongo.bson.to.list功能,但 amongo.cursor.to.list可能就是您想要的。也许值得向驱动程序开发人员寻求建议。
一个巧妙的解决方案可能是创建一个新集合,其文档是每个原始文档的 100000 个数据“块”。然后,可以使用 有效地读取这些内容中的每一个mongo.bson.to.list。可以使用 mongo 服务器 MapReduce 功能构建分块集合。
| 归档时间: |
|
| 查看次数: |
1542 次 |
| 最近记录: |