Mongoid Group By或MongoDb group by in rails [英] Mongoid Group By or MongoDb group by in rails
问题描述
我有一个mongo表,其中包含如下统计数据....
I have a mongo table that has statistical data like the following....
- course_id
- 状态
which is a string, played or completed
使用 Mongoid的时间戳记功能
- course_id
- status
which is a string, played or completed
- and timestamp information using Mongoid's Timestamping feature
所以我的课如下...
so my class is as follows...
class Statistic
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Paranoia
field :course_id, type: Integer
field :status, type: String # currently this is either play or complete
我想获得一门课程每天总播放次数的计数.例如 12年8月1日有2场比赛,12年8月2日有6场比赛.等等,因此,我将使用带有"course_id"和"action"的created_at timestamp字段.问题是我没有在Mongoid中看到按方法分组.我相信mongodb现在有一个了,但是我不确定在rails 3中如何做到这一点.
I want to get a daily count of total # of plays for a course. So for example... 8/1/12 had 2 plays, 8/2/12 had 6 plays. Etc. I would therefore be using the created_at timestamp field, with course_id and action. The issue is I don't see a group by method in Mongoid. I believe mongodb has one now, but I'm unsure of how that would be done in rails 3.
我可以使用每个表浏览整个表,并以递增的方式一起破解一些地图或哈希,但是如果该课程具有100万个视图,则检索并迭代超过100万条记录可能会很混乱.有一种干净的方法可以做到这一点吗?
I could run through the table using each, and hack together some map or hash in rails with incrementation, but what if the course has 1 million views, retrieving and iterating over a million records could be messy. Is there a clean way to do this?
推荐答案
如注释中所述,您可以为此目的使用map/reduce.因此,您可以在模型中定义以下方法( http://mongoid.org/en/mongoid/docs /querying.html#map_reduce )
As mentioned in comments you can use map/reduce for this purpose. So you could define the following method in your model ( http://mongoid.org/en/mongoid/docs/querying.html#map_reduce )
def self.today
map = %Q{
function() {
emit(this.course_id, {count: 1})
}
}
reduce = %Q{
function(key, values) {
var result = {count: 0};
values.forEach(function(value) {
result.count += value.count;
});
return result;
}
}
self.where(:created_at.gt => Date.today, status: "played").
map_reduce(map, reduce).out(inline: true)
end
这将导致以下结果:
[{"_id"=>1.0, "value"=>{"count"=>2.0}}, {"_id"=>2.0, "value"=>{"count"=>1.0}}]
其中_id
是course_id
,count
是播放次数.
MongoDB中也有专用的 group 方法,但我不确定如何使用Mongoid 3中裸露的mongodb集合.我还没有机会深入研究代码.
There is also dedicated group method in MongoDB but I am not sure how to get to the bare mongodb collection in Mongoid 3. I did not have a chance to dive into code that much yet.
您可能想知道为什么我发出一个文档{count: 1}
,因为它无关紧要,我本可以发出空文档或任何东西,然后对每个值始终向result.count加1.问题是,如果仅对特定键执行一次发射操作(在我的示例中course_id
仅被播放一次),则不会调用reduce,因此最好以相同的格式发射文档.
You may wonder why I emit a document {count: 1}
as it does not matter that much and I could have just emitted empty document or anything and then always add 1 to the result.count for every value. The thing is that reduce is not called if only one emit has been done for particular key (in my example course_id
has been played only once) so it is better to emit documents in the same format as result.
这篇关于Mongoid Group By或MongoDb group by in rails的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!