我什么时候绝对需要MongoDB聚合中的$out操作符?

我什么时候绝对需要MongoDB聚合中的$out操作符?,mongodb,mongodb-query,pymongo,bigdata,Mongodb,Mongodb Query,Pymongo,Bigdata,关于$out的MongoDB聚合文档说: “获取聚合管道返回的文档并将其写入指定的集合。$out运算符必须是管道中的最后一个阶段。$out运算符允许聚合框架返回任意大小的结果集。” 因此,一个问题可能是聚合可能会耗尽内存或使用大量内存。但是$out在这里有什么帮助呢?最终,如果聚合返回了很多bucket,那么它们将首先保存在内存中。当您有一个特定的用例需要很长时间才能计算,但不需要始终是当前的时,$out操作符非常有用 假设你有一个网站,你想在frontpage上列出当前十大最受欢迎的文章(过

关于$out的MongoDB聚合文档说:

“获取聚合管道返回的文档并将其写入指定的集合。$out运算符必须是管道中的最后一个阶段。$out运算符允许聚合框架返回任意大小的结果集。”


因此,一个问题可能是聚合可能会耗尽内存或使用大量内存。但是$out在这里有什么帮助呢?最终,如果聚合返回了很多bucket,那么它们将首先保存在内存中。

当您有一个特定的用例需要很长时间才能计算,但不需要始终是当前的时,$out操作符非常有用

假设你有一个网站,你想在frontpage上列出当前十大最受欢迎的文章(过去60分钟内点击率最高)。要创建此统计信息,您需要使用如下管道解析访问日志集合:

  • 美元匹配最后一个小时
  • $group按项目id和用户筛选重新加载
  • $group(按文章id再次分组)以获取每个文章和用户的点击次数
  • 按计数排序
  • $10个结果限制
当你有一个非常受欢迎的网站,有很多内容,这可能是一个相当重的负载聚合。当你把它放在frontpage上时,你需要为每一次frontpage点击做这件事。这可能会在数据库上造成相当严重的负载,并大大延长加载时间

我们如何解决这个问题


我们使用cronjob每分钟执行一次聚合,它使用$out将聚合后的前十名列表放入一个新集合中,而不是在每个命中的页面上执行聚合。然后可以直接查询该集合中的缓存结果。从10个文档集合中获取所有10个结果要比始终执行聚合快得多。

当您有一个特定的用例需要花费很长时间进行计算,但不需要始终保持当前状态时,$out操作符非常有用

假设你有一个网站,你想在frontpage上列出当前十大最受欢迎的文章(过去60分钟内点击率最高)。要创建此统计信息,您需要使用如下管道解析访问日志集合:

  • 美元匹配最后一个小时
  • $group按项目id和用户筛选重新加载
  • $group(按文章id再次分组)以获取每个文章和用户的点击次数
  • 按计数排序
  • $10个结果限制
当你有一个非常受欢迎的网站,有很多内容,这可能是一个相当重的负载聚合。当你把它放在frontpage上时,你需要为每一次frontpage点击做这件事。这可能会在数据库上造成相当严重的负载,并大大延长加载时间

我们如何解决这个问题


我们使用cronjob每分钟执行一次聚合,它使用$out将聚合后的前十名列表放入一个新集合中,而不是在每个命中的页面上执行聚合。然后可以直接查询该集合中的缓存结果。从10个文档集合中获取所有10个结果要比始终执行该聚合快得多。

如果您的问题实际上是收到一个错误,说“BSON size limit EXCED”或类似的话,
$out
在这里没有帮助。正如文档所述,它只是输出到一个集合。这是MongoDB 2.6引入的特性,但游标也是如此。两者都允许总输出大于16MB(这在以前的版本中是一个限制),但每个文档的限制仍然适用。如果您的问题实际上类似于收到一个错误,说“BSON size limit Oversed”或类似的话,那么
$out
在这里将没有帮助。正如文档所述,它只是输出到一个集合。这是MongoDB 2.6引入的特性,但游标也是如此。两者都允许总输出大于16MB(这在以前的版本中是一个限制),但每个文档的限制仍然适用。感谢澄清。这里还有一个问题。我们也可以将聚合结果缓存在一些缓存中,比如memcache/redis,并且可以对结果设置过期时间。在Mongo中缓存它有什么好处吗?我们如何知道它是“旧的”,需要再次运行聚合。@NipunTalukdar当然可以,当您想安装另一个数据库系统来托管、管理和维护时。但是,当您一次又一次地查询相同的文档时,MongoDB会将它们放入RAM中,这使其速度几乎与专用内存数据库(如Memcached)一样快。如何定期运行操作取决于您使用服务器端构建应用程序的技术。感谢您的澄清。这里还有一个问题。我们也可以将聚合结果缓存在一些缓存中,比如memcache/redis,并且可以对结果设置过期时间。在Mongo中缓存它有什么好处吗?我们如何知道它是“旧的”,需要再次运行聚合。@NipunTalukdar当然可以,当您想安装另一个数据库系统来托管、管理和维护时。但是,当您一次又一次地查询相同的文档时,MongoDB会将它们放入RAM中,这使其速度几乎与专用内存数据库(如Memcached)一样快。如何定期运行操作取决于您使用服务器端构建应用程序的技术。