MongoDB聚合与MapReduce一样慢?

MongoDB聚合与MapReduce一样慢?,mongodb,mapreduce,pymongo,nosql,Mongodb,Mapreduce,Pymongo,Nosql,我只是从mongo db开始,尝试做一些简单的事情。我用包含“item”属性的数据集合填充数据库。我想尝试计算每件物品在收藏中的时间 文档示例: { "_id" : ObjectId("50dadc38bbd7591082d920f0"), "item" : "Pons", "lines" : 37 } 因此,我设计了这两个函数来实现MapReduce(使用pymongo用python编写) 这

我只是从mongo db开始,尝试做一些简单的事情。我用包含“item”属性的数据集合填充数据库。我想尝试计算每件物品在收藏中的时间

文档示例:

{ "_id" : ObjectId("50dadc38bbd7591082d920f0"), "item" : "Pons", "lines" : 37 }
因此,我设计了这两个函数来实现MapReduce(使用pymongo用python编写)

这很有魅力,所以我开始收藏。大约有30000个文档,mapreduce的持续时间已经超过一秒。。。因为NoSQL在吹嘘速度,我想我一定是做错了什么

Stack Overflow的一个问题让我检查了mongodb的聚合特性。所以我尝试使用group+sum+sort。我想到了这个:

db.wikipedia.aggregate(
 { $group: { _id: "$item", count: { $sum: 1  }  } }, 
 { $sort: {count: 1}  }
)

这段代码工作得很好,给了我与mapreduce集相同的结果,但速度同样慢。我做错什么了吗?我真的需要使用hadoop等其他工具来获得更好的性能吗?

我将给出一个答案,基本上总结我的评论。我不能代表Hadoop等其他技术发言,因为我还没有找到时间使用它们,但我可以代表MongoDB发言

不幸的是,对于任何数据库,您都在使用两种最糟糕的运算符:计算字段和全表扫描上的分组(或不同)。在这种情况下,聚合框架必须计算字段、组,然后在内存中()对计算字段进行排序。对于MongoDB来说,这是一项效率极低的任务,事实上很可能是任何数据库

没有一种简单的方法可以根据您自己的应用程序实时执行此操作。如果您不需要立即返回结果,Map reduce可能是一种解决方法,但因为我猜您并不真的想等待此类结果,所以默认方法只是彻底根除该组

您可以通过预聚合来实现这一点。因此,您可以创建另一个
分组的\u wikipedia
集合,并在应用程序中使用
upsert()
和原子运算符(如
$set
$inc
)来管理该集合,以确保每个
项只获得一行。这可能是解决这个问题最明智的方法


然而,这确实带来了另一个问题,那就是必须管理这个额外的集合以及细节集合
wikipedia
,但我相信这是在这里获得正确性能不可避免的副作用。好处将大于管理额外收集的损失。

$group不能使用索引,然后您在计算字段上进行完整的表扫描和排序,而计算字段又不能使用索引…嗯,是的,我认为这可能很慢,先生,请看$sort上的通知:。如果我是诚实的,我不认为这是工具的错误,但更多的是架构的设计如果你需要实时地做这样的查询,请阅读以下澄清:@Sammaye当你阅读我的结束语时,你会注意到我并没有对工具发火。我还没有使用NoSQL和MongoDB的经验。我只是问出了什么问题。我怎样才能改进我的设计,让它以正确的方式运行。我不是因为愤怒而责备你:)我是在说明我认为问题出在哪里。嗯,一个额外的预聚合集合是一个很好的开始,因此每次你添加一个
项目
时,你将该行(可能在你的应用程序中)ping到另一个集合中,在那里它将使用
$inc
操作符上传该数据。这可能是最好的方法,不用读太多。当然,这意味着您要管理两个集合,但管理它们比查询要更快、更容易。@Sammaye老实说,我发现您的反馈非常有建设性,所以我只是想确定;)我也在考虑一个两个集合的解决方案。在NoSQL故事中,尝试创建一个更复杂的查询更有意义。非常感谢您指出,在计算字段上进行排序确实有点慢:)但是如果您有一个包含800万条目的集合,并且您在其上不断运行map&reduce以保持“缓存”最新,这是否会降低数据库的速度?@RobertReiz它可能会降低数据库的速度,这需要考虑很多因素。我的意思是你确实有JS引擎的重量,但是JS enigne不再是单线程的,它可以在进行处理时释放db上的锁,所以问题是一旦MR完成后,需要向db写入IO,但是,如果你运行的MR只选择,每5分钟10000行,您会发现MongoDB可以非常愉快地处理这些问题,我不太关心客户机,而是MongoDB流程。假设我有800万个条目,每个条目MongoDB MR需要5分钟,那么我需要27天来计算所有缓存。这与实时性相差甚远:-@RobertReiz这是mongod进程,mongod进程将启动其内置的JS enigne,2.2+版本的v8。您收藏的每个条目都需要mongodb 5分钟来计算?等等,怎么说,为什么?@RobertReiz清楚地记得,如果你每5分钟再运行一次所有800万条记录,那就不是什么增量MR工作了
db.wikipedia.aggregate(
 { $group: { _id: "$item", count: { $sum: 1  }  } }, 
 { $sort: {count: 1}  }
)