Como se menciona en los comentarios, puede usar map/reduce para este propósito. Entonces podría definir el siguiente método en su modelo ( 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
lo que daría como resultado el siguiente resultado:
[{"_id"=>1.0, "value"=>{"count"=>2.0}}, {"_id"=>2.0, "value"=>{"count"=>1.0}}]
donde _id
es el course_id
y count
es el número de reproducciones.
También hay un método de grupo dedicado en MongoDB, pero no estoy seguro de cómo llegar a la colección mongodb desnuda en Mongoid 3. Todavía no tuve la oportunidad de sumergirme tanto en el código.
Quizás se pregunte por qué emito un documento {count: 1}
ya que no importa tanto y podría haber emitido un documento vacío o cualquier cosa y luego siempre agregar 1 al resultado. contar para cada valor. La cuestión es que reduce no se llama si solo se ha realizado una emisión para una clave en particular (en mi ejemplo, course_id
se ha reproducido una sola vez), por lo que es mejor emitir documentos en el mismo formato como resultado.