MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Mongoid Group By oder MongoDb Group By in Schienen

Wie in den Kommentaren erwähnt, können Sie zu diesem Zweck map/reduce verwenden. Sie könnten also die folgende Methode in Ihrem Modell definieren ( 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

was zu folgendem Ergebnis führen würde:

[{"_id"=>1.0, "value"=>{"count"=>2.0}}, {"_id"=>2.0, "value"=>{"count"=>1.0}}] 

wobei _id ist die course_id und count ist die Anzahl der Spiele.

Es gibt auch eine dedizierte Gruppenmethode in MongoDB, aber ich bin mir nicht sicher, wie ich in Mongoid 3 zur bloßen Mongodb-Sammlung gelangen soll. Ich hatte noch keine Gelegenheit, so viel in Code einzutauchen.

Sie fragen sich vielleicht, warum ich ein Dokument {count: 1} aussende da es nicht so wichtig ist und ich hätte einfach ein leeres Dokument oder irgendetwas ausgeben und dann immer 1 zum result.count für jeden Wert hinzufügen können. Die Sache ist, dass Reduce nicht aufgerufen wird, wenn nur ein Emit für einen bestimmten Schlüssel durchgeführt wurde (in meinem Beispiel course_id wurde nur einmal abgespielt), daher ist es besser, Dokumente im selben Format wie das Ergebnis auszugeben.