Như đã đề cập trong phần nhận xét, bạn có thể sử dụng bản đồ / thu nhỏ cho mục đích này. Vì vậy, bạn có thể xác định phương thức sau trong mô hình của mình (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
mà sẽ dẫn đến kết quả sau:
[{"_id"=>1.0, "value"=>{"count"=>2.0}}, {"_id"=>2.0, "value"=>{"count"=>1.0}}]
ở đâu _id
là course_id
và count
là số lượt chơi.
Cũng có phương thức nhóm dành riêng trong MongoDB nhưng tôi không chắc làm thế nào để truy cập bộ sưu tập mongodb trần trong Mongoid 3. Tôi chưa có cơ hội tìm hiểu sâu về mã.
Bạn có thể thắc mắc tại sao tôi tạo ra một tài liệu {count: 1}
vì nó không quan trọng nhiều và tôi có thể chỉ tạo ra tài liệu trống hoặc bất cứ thứ gì và sau đó luôn thêm 1 vào result.count cho mọi giá trị. Vấn đề là giảm không được gọi nếu chỉ có một lần phát được thực hiện cho khóa cụ thể (trong ví dụ của tôi là course_id
chỉ được phát một lần) vì vậy tốt hơn là bạn nên phát ra các tài liệu ở cùng một định dạng.