我有一个具有类似于下面的统计数据蒙戈表....
- COURSE_ID
- 状态
which is a string, played or completed
- 并且使用时间戳信息Mongoid的时间戳功能
所以我的课是如下...
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次。 等我因此将使用created_at时间戳字段,以COURSE_ID和行动。 问题是我不Mongoid看到一组由方法。 我相信MongoDB的有一个了,但我不能确定的,将如何在轨道3来完成。
我可以通过使用每个表运行,和黑客一起与增量轨一些地图或散列,但如果过程中有1点亿的观点,检索和遍历一百万条记录可能是凌乱。 有没有干净的方式做到这一点?
正如评论指出,可以使用的map / reduce实现此目的。 所以,你可以在你的模型中定义了以下方法( 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的方法,但我不知道怎么去裸MongoDB的集合中Mongoid 3.我没有机会深入到代码还得多说。
你可能想知道为什么我发出的文件{count: 1}
因为它不管那么多了,我可能只是发出空洞的文件或任何东西,然后随时添加1到result.count的每一个值。 问题是,降低不叫,如果只有一个EMIT已经为特定的键完成(在我的例子course_id
已经只有一次出场),所以最好是放出文档的格式相同的结果。
使用Mongoid
stages = [{
"$group" => { "_id" => { "date_column_name"=>"$created_at" }},
"plays_count" => { "$sum" => 1 }
}]
@array_of_objects = ModelName.collection.aggregate(stages, {:allow_disk_use => true})
要么
stages = [{
"$group" => {
"_id" => {
"year" => { "$year" => "$created_at" },
"month" => { "$month" => "$created_at" },
"day" => { "$dayOfMonth" => "$created_at" }
}
},
"plays_count" => { "$sum" => 1 }
}]
@array_of_objects = ModelName.collection.aggregate(stages, {:allow_disk_use => true})
通过使用mongoid按照以下组的链接
https://taimoorchangaizpucitian.wordpress.com/2016/01/08/mongoid-group-by-query/ https://docs.mongodb.org/v3.0/reference/operator/aggregation/group/