【问题标题】:R: Speeding up data import using rmongodbR:使用 rmongodb 加速数据导入
【发布时间】:2016-07-22 04:12:36
【问题描述】:

考虑一个 Mongo 数据库,其中每个条目都具有以下数据结构。

{
    "_id" : ObjectId("numbersandletters"),
    "hello" : 0,
    "this" : "AUTO",
    "is" : "34.324.25.53",
    "an" : "7046934",
    "example" : 0,
    "data" : {
        "google" : "SEARCH",
        "wikipedia" : "Placeholder",
        "twitch" : "2016",
        "twitter" : "More_placeholder",
        "facebook" : "Run out of ideas",
        "stackoverflow" : "is great",
    },
    "schema" : "",
    "that" : "",
    "illustrates" : 0,
    "the_point" : "/somethinghere.html",
    "timestamp" : ISODate("2016-03-05T04:53:20.000Z")
}

上述数据结构是单个数据观察的示例。数据库中有大约 1200 万个观测值。数据结构中的字段“this”可以采用“AUTO”或“MANUAL”的属性。

我目前正在使用 rmongodb 库将 Mongo 中的一些数据导入 R,然后将结果列表转换为数据框。

R代码如下:

library(rmongodb)

m <- mongo.create(host = "localhost", db = "example")

rawData <- mongo.find.all(m, "example.request", query = list(this = "AUTO"), 
                           fields = list(hello = 1L, is = 1L, an = 1L, data.facebook = 1L, the_point = 1L))

rawData <- data.frame(matrix(unlist(rawData), nrow = length(rawData), byrow = TRUE))

上述代码适用于相对较小的数据集(例如,

是否有更智能(因此更快)的方式从 Mongo 导入数据,然后将生成的数据投影到 R 数据帧中?

干杯。

【问题讨论】:

标签: r mongodb mongolite mongolitedt


【解决方案1】:

看看mongolite 包。您应该为几百万个结果获得一些速度提升。

library(mongolite)
mongo <- mongo(collection = "request", db = "example", url = "mongodb://localhost") 

df <- mongo$find(query = '{ "this" : "AUTO" }', fields = '{ "_id" : 0, "hello" : 1, "is" : 1, "an" : 1, "data.facebook" : 1, "the_point" : 1 }')

但是,随着结果集的增长,转换为 data.frame 的过程会变慢。

出于这个原因,我一直在尝试通过删除递归调用来加速 mongolite,以尝试扁平化查询中的 JSON 结构,并依靠 data.tablerbindlist 光标(以避免 mongolite::simplify将其转换为 data.frame 的函数)。这将返回一个data.table 对象

mongolitedt package仍在开发中,您发送的任何查询都必须能够通过rbindlist 强制转换为data.table。在 pacakge 主页上,我添加了一些基准来显示它所带来的加速。

## install the package with
library(devtools)
install_github("SymbolixAU/mongolitedt")

library(mongolitedt)
## requires data.table and mongolite

# rm(mongo); gc()
mongo <- mongo(collection = "request", db = "example", url = "mongodb://localhost") 
bind_mongolitedt(mongo)   ## bind dt functions to mongolite connection object


dt <- mongo$finddt(query = '{ "this" : "AUTO" }', fields = '{ "_id" : 0, "hello" : 1, "is" : 1, "an" : 1, "data.facebook" : 1, "the_point" : 1 }')

【讨论】:

  • 太棒了!我从未使用过mongolite,但它似乎非常快。两件事:(1)流数据!我的 mongodb 不断增加,现在我每天午夜提取数据并对数据进行一些分析;持续流式传输数据将是一个令人难以置信的补充;我没有意识到R可以做到这一点......!我可以去任何地方获取有关此的更多信息? (2) 当使用mongo$finddt 时,是否有强制它使用use.names = TRUE, fill = TRUErbindlist 函数?
  • @Futh For (2) - 我已将其更新为对所有 rbindlsits 使用 rbindlist(..., use.names = T, fill = T)。 (我以为我已经这样做了,但我在一个地方错过了它)。
  • @Futh 对于 (1) - 您是否在了解来自 jsonlite 的有关 stream_in 函数的更多信息?
  • 太棒了!我注意到rbindlist(..., use.names = T, fill = T) 不存在try_rbind_page.R,这使我之前的尝试搞砸了。谢谢你改变这个!我今天对 stream_in 函数做了一些阅读,这可能非常有用......我正在开发一个程序,对 Mongo 的传入数据进行“实时”分析(包括数据的分析和绘图)...... stream_instream_out 函数可能有用;只是希望有更多的文档。
  • @Futh 您是否研究过spark / sparkR 方法?我自己对它不太熟悉,但可能有用。您是否在线托管您的项目?我很想看看你是怎么做的?
猜你喜欢
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
  • 2017-09-23
相关资源
最近更新 更多