Comme mentionné dans les commentaires, vous pouvez utiliser map/reduce à cette fin. Vous pouvez donc définir la méthode suivante dans votre modèle ( 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
ce qui donnerait le résultat suivant :
[{"_id"=>1.0, "value"=>{"count"=>2.0}}, {"_id"=>2.0, "value"=>{"count"=>1.0}}]
où _id
est le course_id
et count
est le nombre de parties.
Il existe également une méthode de groupe dédiée dans MongoDB, mais je ne sais pas comment accéder à la collection mongodb nue dans Mongoid 3. Je n'ai pas encore eu l'occasion de plonger autant dans le code.
Vous vous demandez peut-être pourquoi j'émets un document {count: 1}
car cela n'a pas beaucoup d'importance et j'aurais pu simplement émettre un document vide ou quoi que ce soit, puis toujours ajouter 1 au result.count pour chaque valeur. Le fait est que reduce n'est pas appelé si une seule émission a été effectuée pour une clé particulière (dans mon exemple course_id
n'a été lu qu'une seule fois) il est donc préférable d'émettre des documents au même format que le résultat.