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