ruby-on-rails - 如何使用 Mongoid 和 Rails 对结果进行分组?

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

我有一个使用 Mongoid 连接到 MongoDB 的模型事件:

class Event
  include Mongoid::Document
  include Mongoid::Timestamps

  field :user_name,   type: String
  field :action,      type: String
  field :ip_address,  type: String

  scope :recent,  -> { where(:created_at.gte => 1.month.ago) }    
end

通常当我使用 ActiveRecord 时,我可以执行以下操作来对结果进行分组:

@action_counts  = Event.group('action').where(:user_name =>"my_name").recent.count

我得到以下格式的结果:

{"action_1"=>46, "action_2"=>36, "action_3"=>41, "action_4"=>40, "action_5"=>37}

使用 Mongoid 做同样事情的最佳方法是什么?

提前致谢

最佳答案

我认为你必须使用map/reduce 来做到这一点。看看这个SO问题了解更多细节:

Mongoid Group By or MongoDb group by in rails

否则,您只需使用 Enumerable 中的 group_by 方法即可。效率较低,但除非您有数十万个文档,否则它应该可以解决问题。

编辑:在本例中使用 map/reduce 的示例

我不太熟悉它,但通过阅读文档和尝试,我无法重现您想要的完全相同的哈希值,但请尝试以下操作:

def self.count_and_group_by_action
  map = %Q{
    function() {
      key = this.action;
      value = {count: 1};
      emit(key, value);
      # emit a new document {"_id" => "action", "value" => {count: 1}}
      # for each input document our scope is applied to
    }
  }

  # the idea now is to "flatten" the emitted documents that
  # have the same key. Good, but we need to do something with the values
  reduce = %Q{
    function(key, values) {
      var reducedValue = {count: 0};
      # we prepare a reducedValue
      # we then loop through the values associated to the same key,
      # in this case, the 'action' name
      values.forEach(function(value) {
        reducedValue.count += value.count; # we increment the reducedValue - thx captain obvious
      });
      # and return the 'reduced' value for that key,
      # an 'aggregate' of all the values associated to the same key
      return reducedValue;
    }
  }

  self.map_reduce(map, reduce).out(inline: true)
  # we apply the map_reduce functions
  # inline: true is because we don't need to store the results in a collection
  # we just need a hash
end

所以当你打电话时:

Event.where(:user_name =>"my_name").recent.count_and_group_by_action

它应该返回类似:

[{ "_id" => "action1", "value" => { "count" => 20 }}, { "_id" => "action2" , "value" => { "count" => 10 }}]

免责声明:我不是 mongodb 也不是 mongoid 专家,我的示例基于我在引用的 SO 问题和 Mongodb/Mongoid 在线文档中找到的内容,任何改进此问题的建议将不胜感激。

资源:

http://docs.mongodb.org/manual/core/map-reduce/ http://mongoid.org/en/mongoid/docs/querying.html#map_reduce

Mongoid Group By or MongoDb group by in rails

关于ruby-on-rails - 如何使用 Mongoid 和 Rails 对结果进行分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25392342/

相关文章:

node.js - 如何使用 NodeJS 向 mongodb 执行批量插入

mysql - 如何在 Rails 中测试或调试我的迁移脚本?

javascript - 将字符串更新为 mongodb 中的 Date 对象

ruby-on-rails - Rails Redis过期方法

arrays - 在 MongoDB 中查找包含专门包含特定文档的数组的文档

mongodb - 如何在 MongoDB 中自定义 $group 输出?

mongodb - 计算 MongoDB 集合中的字段

mongodb - 根据MongoDB中的条件查询每个组的最大N条记录?

ruby-on-rails - 从外部访问 WEBrick 服务器

ruby-on-rails - 创建模型实例时如何建立 has_and_belongs_to_many 关联