Zoals vermeld in opmerkingen kunt u hiervoor kaart/verkleinen gebruiken. U kunt dus de volgende methode in uw model definiëren ( 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
wat zou resulteren in het volgende resultaat:
[{"_id"=>1.0, "value"=>{"count"=>2.0}}, {"_id"=>2.0, "value"=>{"count"=>1.0}}]
waar _id
is de course_id
en count
is het aantal spelen.
Er is ook een speciale groepsmethode in MongoDB, maar ik weet niet zeker hoe ik bij de kale mongodb-verzameling in Mongoid 3 kan komen. Ik had nog niet de kans om zoveel in code te duiken.
Je vraagt je misschien af waarom ik een document verzend {count: 1}
omdat het niet zoveel uitmaakt en ik gewoon een leeg document of iets anders had kunnen verzenden en dan altijd 1 bij het resultaat had kunnen optellen voor elke waarde. Het punt is dat reduce niet wordt aangeroepen als er slechts één emissie is gedaan voor een bepaalde sleutel (in mijn voorbeeld course_id
is slechts één keer afgespeeld), dus het is beter om documenten in hetzelfde formaat als resultaat uit te zenden.