使用 Rs mongolite 正确(插入?更新?)将数据添加到现有集合
Use Rs mongolite to correctly (insert? update?) add data to existing collection
我用 R 编写了以下函数(我认为)在更新我的 mongo 数据库集合方面做得很差。
library(mongolite)
con <- mongolite::mongo(collection = "mongo_collection_1", db = 'mydb', url = 'myurl')
myRdataframe1 <- con$find(query = '{}', fields = '{}')
rm(con)
con <- mongolite::mongo(collection = "mongo_collection_2", db = 'mydb', url = 'myurl')
myRdataframe2 <- con$find(query = '{}', fields = '{}')
rm(con)
... code to update my dataframes (rbind additional rows onto each of them) ...
# write dataframes to database
write.dfs.to.mongodb.collections <- function() {
collections <- c("mongo_collection_1", "mongo_collection_2")
my.dataframes <- c("myRdataframe1", "myRdataframe2")
# loop dataframes, write colllections
for(i in 1:length(collections)) {
# connect and add data to this table
con <- mongo(collection = collections[i], db = 'mydb', url = 'myurl')
con$remove('{}')
con$insert(get(my.dataframes[i]))
con$count()
rm(con)
}
}
write.dfs.to.mongodb.collections()
我的数据帧 myRdataframe1
和 myRdataframe2
是非常大的数据帧,目前约 10 万行和约 50 列。每次我的脚本 运行s,它:
- 使用 con$find('{}') 将 mongodb 集合拉入 R,保存为数据框
myRdataframe1
- 从数据提供者中抓取新数据,将其作为新行附加到
myRdataframe1
- 使用con$remove()和con$insert完全删除mongodb集合中的数据,然后重新插入整个
myRdataframe1
最后一个要点是不确定的,因为我 运行 这个 R 脚本每天都在 cronjob 中,我不喜欢每次我完全擦除 mongo 数据库集合并重新 -将 R 数据帧插入集合。
如果我删除 con$remove() 行,我会收到一条错误消息,指出我有重复的 _id 键。看来我不能简单地使用 con$insert().
追加
非常感谢对此的任何想法!
当您尝试根据主键将已存在于数据库中的文档插入 MongoDB 时,您将遇到重复键异常。为了解决这个问题,您可以在 con$insert
:
之前使用类似的方法简单地取消设置 _id
列
my.dataframes[i]$_id <- NULL
这样,新插入的文档会自动得到一个新的_id
分配。
你可以使用 upsert ( 它匹配符合第一个条件的文档,如果找到它会更新它,如果没有它会插入一个新的,
首先你需要从每个文档中分离出 id
_id= my.dataframes[i]$_id
updateData = my.dataframes[i]
updateData$_id <- NULL
然后使用 upsert(可能有一些更简单的方法在 R 中连接字符串)
con$update(paste('{"_id":"', _id, '"}' ,sep="" ) , paste('{"$set":', updateData,'}', sep=""), upsert = TRUE)
我用 R 编写了以下函数(我认为)在更新我的 mongo 数据库集合方面做得很差。
library(mongolite)
con <- mongolite::mongo(collection = "mongo_collection_1", db = 'mydb', url = 'myurl')
myRdataframe1 <- con$find(query = '{}', fields = '{}')
rm(con)
con <- mongolite::mongo(collection = "mongo_collection_2", db = 'mydb', url = 'myurl')
myRdataframe2 <- con$find(query = '{}', fields = '{}')
rm(con)
... code to update my dataframes (rbind additional rows onto each of them) ...
# write dataframes to database
write.dfs.to.mongodb.collections <- function() {
collections <- c("mongo_collection_1", "mongo_collection_2")
my.dataframes <- c("myRdataframe1", "myRdataframe2")
# loop dataframes, write colllections
for(i in 1:length(collections)) {
# connect and add data to this table
con <- mongo(collection = collections[i], db = 'mydb', url = 'myurl')
con$remove('{}')
con$insert(get(my.dataframes[i]))
con$count()
rm(con)
}
}
write.dfs.to.mongodb.collections()
我的数据帧 myRdataframe1
和 myRdataframe2
是非常大的数据帧,目前约 10 万行和约 50 列。每次我的脚本 运行s,它:
- 使用 con$find('{}') 将 mongodb 集合拉入 R,保存为数据框
myRdataframe1
- 从数据提供者中抓取新数据,将其作为新行附加到
myRdataframe1
- 使用con$remove()和con$insert完全删除mongodb集合中的数据,然后重新插入整个
myRdataframe1
最后一个要点是不确定的,因为我 运行 这个 R 脚本每天都在 cronjob 中,我不喜欢每次我完全擦除 mongo 数据库集合并重新 -将 R 数据帧插入集合。
如果我删除 con$remove() 行,我会收到一条错误消息,指出我有重复的 _id 键。看来我不能简单地使用 con$insert().
追加非常感谢对此的任何想法!
当您尝试根据主键将已存在于数据库中的文档插入 MongoDB 时,您将遇到重复键异常。为了解决这个问题,您可以在 con$insert
:
_id
列
my.dataframes[i]$_id <- NULL
这样,新插入的文档会自动得到一个新的_id
分配。
你可以使用 upsert ( 它匹配符合第一个条件的文档,如果找到它会更新它,如果没有它会插入一个新的, 首先你需要从每个文档中分离出 id
_id= my.dataframes[i]$_id
updateData = my.dataframes[i]
updateData$_id <- NULL
然后使用 upsert(可能有一些更简单的方法在 R 中连接字符串)
con$update(paste('{"_id":"', _id, '"}' ,sep="" ) , paste('{"$set":', updateData,'}', sep=""), upsert = TRUE)