【问题标题】:Aggregate functions with MongoDB/Mongoid and calculated fields使用 MongoDB/Mongoid 和计算字段聚合函数
【发布时间】:2011-07-22 00:33:00
【问题描述】:

我正在迁移现有的 Rails 应用程序以使用 MongoDB(使用 Mongoid),但在弄清楚如何像使用 MySQL 那样进行聚合时遇到了一些麻烦。

以前我有类似 SELECT DATE(created_at) AS day, SUM(amount) AS amount GROUP BY day 的东西,它会返回一个集合,您可以像这样在模板中循环访问:

:day => '2011-03-01', :amount => 55.00 
:day => '2011-03-02', :amount => 45.00
etc...

有谁知道如何在 Mongoid 中做到这一点?该模型非常简单:

class Conversion
  include Mongoid::Document
  include Mongoid::Timestamps

  field :amount,      :type => Float, :default => 0.0
  ...
  # created_at generated automatically, standard Rails...
end

谢谢!

-Avishai

【问题讨论】:

    标签: ruby-on-rails mongodb mapreduce mongodb-query mongoid


    【解决方案1】:

    不幸的是,这比你想象的要难。

    我的理解是 Mongoid 本身不支持在一个查询中进行分组和添加,为此,您需要直接使用 MongoDB 驱动程序进行映射/归约。我使用与您的数据结构相似的数据结构运行此示例,但在翻译过程中可能会出现一些错误,如果您有任何问题,请告诉我,我会尝试修改它。

    首先,您需要定义 map 和 reduce 函数。这些必须存储为 JavaScript 字符串。

    map = "function(){ emit(new Date(this.created_at.getYear(), this.created_at.getMonth(), this.created_at.getDate()), {amount: this.amount}); };"
    reduce = "function(key, values){ var sum = 0; values.forEach(function(doc){ sum += doc.amount; }); return {amount: sum};};"
    

    然后你直接在集合上调用map_reduce,在这种情况下:

    Conversion.collection.map_reduce(map, reduce).find.to_a
    

    这将返回一个哈希数组,如下所示:

    [{"_id"=>Sat Dec 13 13:00:00 UTC 0110, "value"=>{"amount"=>55.0}}, {"_id"=>Sat Jan 17 13:00:00 UTC 0111, "value"=>{"amount"=>45.0}}] 
    

    【讨论】:

    • 这确实有效!使用起来比标准的 ActiveRecord 样式查询更痛苦,因为你必须得到result['_id']['value']['amount'] 的结果,但很酷:-)
    【解决方案2】:

    Mongoid 还有一些用于简单计算的快捷方式:

    您可以将以下内容添加到任何范围:

    .max(:age)
    .min(:quantity)
    .sum(:total)
    

    请注意,这不会像 m/r 那样快,因为它在应用程序和 mongo 中循环游标。但是如果你的结果集不是那么大,它是一个不错的选择

    这里是来源:https://github.com/mongoid/mongoid/blob/2.4.0-stable/lib/mongoid/contexts/enumerable.rb

    还请继续关注即将推出的聚合框架:http://www.mongodb.org/display/DOCS/Aggregation+Framework

    【讨论】:

      猜你喜欢
      • 2019-04-06
      • 2013-09-01
      • 2012-10-11
      • 1970-01-01
      • 1970-01-01
      • 2020-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多