R:使用 rmongodb 加速数据导入
R: Speeding up data import using rmongodb
考虑一个 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",
"Whosebug" : "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))
以上代码适用于相对较小的数据集(例如,< 100 万个观察值),但对于 1200 万个数据集来说速度很慢。
是否有更智能(因此更快)的方法从 Mongo 导入数据,然后将生成的数据投影到 R 数据框中?
干杯。
看看 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.table
到 rbindlist
光标(避免 mongolite::simplify
函数将它变成 data.frame)。这个returns一个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 }')
考虑一个 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",
"Whosebug" : "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))
以上代码适用于相对较小的数据集(例如,< 100 万个观察值),但对于 1200 万个数据集来说速度很慢。
是否有更智能(因此更快)的方法从 Mongo 导入数据,然后将生成的数据投影到 R 数据框中?
干杯。
看看 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.table
到 rbindlist
光标(避免 mongolite::simplify
函数将它变成 data.frame)。这个returns一个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 }')