我知道可以在MongoDB命令行中使用group方法,但是我找不到如何在rmongodb库中执行这样的任务。目前,我必须通过一些参数获取所有值,然后循环通过它们添加到新数据框,以防它们不存在。
cursor = mongo.find(mongo, "db.col", list(filterfield="filtervalue"), fields = list(f1=1L, f2=1L))
df = data.frame(f1=character(0), f2=character(0), stringsAsFactors=FALSE)
while(mongo.cursor.next(cursor)){
newf1 = list(mongo.bson.to.list(mongo.cursor.value(cursor)))[[1]]$f1
newf2 = list(mongo.bson.to.list(mongo.cursor.value(cursor)))[[1]]$f2
if(nrow(subset(df, df$f1 == newf1 & df$f2 == newf2)) < 1){
df[nrow(df) + 1, ] = c(newf1, newf2)
}
}
看起来非常低效,因为在MongoDB中对它进行分组需要花费数小时的时间......有没有更简单的直接MongoDB命令?
答案 0 :(得分:1)
这不是那么容易,但你可以做到:-)。最大的挑战是创建bson查询并使用mongodb中的runCommand语法。以下是一些示例代码和您可以在docs.mongodb.org中找到的数据。
示例SQL查询可能如下所示:
SELECT state, SUM(pop) AS totalPop FROM zips GROUP BY state
HAVING pop > (10000)
在mongoDB shell中,你将运行这样的东西。
db.zipcodes.aggregate( { $group :
{ _id : "$state",
totalPop : { $sum : "$pop" }
} },
{ $match : {totalPop : { $gte : 10000 } } }
)
您可以使用命令db.runCommand运行相同的命令,该命令具有以下聚合框架的默认语法:
db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {author : 1,tags : 1}
},
{ $unwind : "$tags" },
{ $group : {
_id : "$tags",
authors : { $addToSet : "$author" }
}
}
] }
);
现在您可以使用以下代码在rmongodb中执行相同的操作:
buf <- mongo.bson.buffer.create()
mongo.bson.buffer.append(buf, "aggregate", "zips")
mongo.bson.buffer.start.array(buf, "pipeline")
mongo.bson.buffer.start.object(buf, "$group")
mongo.bson.buffer.append(buf, "_id", "$state")
mongo.bson.buffer.start.object(buf, "totalPop")
mongo.bson.buffer.append(buf, "$sum", "$pop")
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.start.object(buf, "$match")
mongo.bson.buffer.start.object(buf, "totalPop")
mongo.bson.buffer.append(buf, "$gte", "10000")
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
query <- mongo.bson.from.buffer(buf)
res <- mongo.command(mongo, "test", query)
out <- mongo.bson.to.list(res)
如果这不起作用,请告诉我。