Arn*_*nja 7 mapreduce mongodb nosql pymongo
我刚刚开始使用mongo db并试图做一些简单的事情.我用包含"item"属性的数据集填充了我的数据库.我想尝试计算每个项目在集合中的时间
文件的例子:
{ "_id" : ObjectId("50dadc38bbd7591082d920f0"), "item" : "Pons", "lines" : 37 }
Run Code Online (Sandbox Code Playgroud)
所以我设计了这两个函数来做MapReduce(使用pymongo在python中编写)
all_map = Code("function () {"
" emit(this.item, 1);"
"}")
all_reduce = Code("function (key, values) {"
" var sum = 0;"
" values.forEach(function(value){"
" sum += value;"
" });"
" return sum;"
"}")
Run Code Online (Sandbox Code Playgroud)
这就像一个魅力,所以我开始填充这个系列.在周围30.000文件,在映射缩减已经持续一秒钟以上......因为NoSQL的被吹嘘的速度,我想我一定是在做什么错了!
Stack Overflow的一个问题让我查看了mongodb的聚合功能.所以我尝试使用group + sum + sort thingies.得出这个:
db.wikipedia.aggregate(
{ $group: { _id: "$item", count: { $sum: 1 } } },
{ $sort: {count: 1} }
)
Run Code Online (Sandbox Code Playgroud)
这段代码工作正常,并给我与mapreduce集相同的结果,但它同样慢.难道我做错了什么?我真的需要使用像hadoop这样的其他工具来获得更好的性能吗?
我将基本上总结一下我的评论.我不能代表像Hadoop这样的其他技术人员,因为我还没有找到时间使用它们,但我可以代表MongoDB.
不幸的是,您正在使用两个最差的运算符用于任何数据库:计算字段和全表扫描分组(或不同).在这种情况下,聚合框架必须计算字段,组,然后在内存中(http://docs.mongodb.org/manual/reference/aggregation/#_S_sort)对计算字段进行排序.对于MongoDB来说,这是一个非常低效的任务,实际上很可能是任何数据库.
没有简单的方法可以根据您自己的应用程序实时执行此操作.如果你不需要立即返回结果,那么Map reduce可能是一种出路但是因为我猜你真的不想等待这种东西,所以默认方法只是完全消除这个组.
您可以通过预聚合来完成此操作.所以,你可以创建另外一个集合grouped_wikipedia,并在您的应用程序管理该使用upsert()与原子运营商如$set和$inc(计数出现),以确保您只得到每一个行item.这可能是解决这个问题最理智的方法.
然而,这确实引起了另一个问题,即必须在详细信息集合中管理这个额外的集合,wikipedia但我相信这是在这里获得正确性能的不可避免的副作用.这些好处将大于必须管理额外收集的损失.
| 归档时间: |
|
| 查看次数: |
1951 次 |
| 最近记录: |