ruby-on-rails - MongoDB - 过滤和计算大型集合以进行统计

标签 ruby-on-rails mongodb mongoid

我正在使用 Mongoid 和 Rails。我有一个名为“数据集”的集合,其中包含大约 600,000 个文档。每个数据集内部都有一个可能存在也可能不存在的关键"file"。文件内部有一个对象(文件)数组。我需要获取所有包含文件的数据集,然后获取这些数据集上所有文件的计数。这就是我所拥有的,但它抛出一个错误,指出它超出了最大文档大小:

total = Dataset.collection.aggregate([
  { '$project' => { files: 1 }},
  { '$unwind' => '$files' },
  { '$group' => {_id: "$_id", count: {'$sum' => 1} } }
])

我可以使用以下命令让它工作,但它太慢了,而且根本没有真正利用数据库的力量:

datasets_with_files = Dataset.where(:files.exists => true)

count = 0
datasets_with_files.each do |dataset|
  count += dataset.files.count
end

count

所以基本上我需要知道 A. 最好的查询类型是什么,以及 B. 如果聚合是最好的方法,如何处理超过最大大小的文档,以便我可以执行这样的查询。

解决方案:

我不需要光标或磁盘使用就可以完成此工作:

Dataset.collection.aggregate([
  { '$match' => { files: { '$exists' => true }}},
  { '$unwind' => '$files' },
  { '$group' => { _id: nil, total_files: { '$sum' => 1 }}}
])[0]['total_files']

最佳答案

您可以使用 $size 直接投影数组字段的大小,因此在 shell 中您可以执行以下操作:

db.test.aggregate([
    {$match: {files: {$exists: true}}},
    {$project: {count: {$size: '$files'}}}
])

在 Ruby 中,它看起来像:

@coll.aggregate([
  { '$match' => { files: { '$exists' => true } } },
  { '$project' => { count: { '$size' => '$files' } } }
])

包含光标选项以克服结果的 16MB 大小限制:

@coll.aggregate([
  { '$match' => { files: { '$exists' => true } } },
  { '$project' => { count: { '$size' => '$files' } } }
], cursor: {})

关于ruby-on-rails - MongoDB - 过滤和计算大型集合以进行统计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28732494/

相关文章:

ruby-on-rails - Ruby 变量值设置为 true

javascript - gem 'gon' - Quotes#index 中的名称错误,未初始化的常量 ActionView::CompiledTemplates::Gon,Rails 5

ruby-on-rails - 发送文件 aws s3 载波

node.js - 将 mongoose 连接到 mongoDB atlas 和 nodejs

ruby-on-rails - Ruby on Rails 更改应用程序的时区

ruby-on-rails - Rails + MongoID - 按属性查询

ruby-on-rails - rails/ ruby : Is there a backbone gem in that doesn't generate coffeescript files?

node.js - 将字符串转换为日期并获取差异

arrays - MongoDB/NodeJS : Looping through query parameter

Ruby mongoid 聚合返回对象