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

Effiziente Möglichkeit, Daten in MongoDB zu speichern:eingebettete Dokumente vs. einzelne Dokumente

Es wäre besser, den ersten Ansatz (einzelne Dokumente) zu verwenden und wenn möglich eine begrenzte Sammlung zu verwenden, da Sie keine schnell wachsende Sammlung haben möchten (mongoid wird Unterstützung für begrenzte Sammlungen in 2.2 haben, das an diesem Wochenende herauskommen würde I rate).

Beim zweiten Ansatz (eingebettete Dokumente) müssen Sie zuerst das Stammdokument für den Benutzer abrufen und dann das Array in der Anwendung durchlaufen, um die Aktivität im Zusammenhang mit dem gesuchten Beitrag zu finden. Mongoid kann es so aussehen lassen, als würde alles in db erledigt, aufgrund der Ähnlichkeit der Syntax beim Auffinden eines eingebetteten Dokuments, aber es iteriert wirklich das Array.

Da Sie die user_id, activity_id und activity_type bereits haben, bevor Sie eine Abfrage durchführen, und Sie nicht möchten, dass die gesamte Liste der Aktivitäten für den Benutzer aus der Datenbank abgerufen wird, wenn Sie nach einer bestimmten Aktivität suchen, bevorzuge ich den ersten Fall. Es würde viel weniger Berechnungen (Suchen) in der Anwendung geben und es würde viel weniger Netzwerkverkehr geben.

Beim Ansatz einzelner Dokumente wäre es großartig, wenn Sie auch einen eindeutigen Index für user_id, activity_id, activity_type erstellen würden. Es wird Ihnen helfen, die Anzahl der Dokumente einzugrenzen. Sie können die Eindeutigkeitsvalidierung (zusätzliche Abfrage) haben, aber das wäre meistens unnötig, wenn Sie den eindeutigen Index haben. Der einzige Vorteil der Validierung ist ein Validierungsfehler, wenn es Duplikate gibt, aber der Index ignoriert doppelte Einträge stillschweigend, es sei denn, Sie bleiben im abgesicherten Modus.

Falls Sie auch möchten, dass die historische Site-Aktivität beibehalten wird, können Sie die Struktur wie folgt verwenden:

class SiteActivity
  include Mongoid::Document
  include Mongoid::Timestamps
  belongs_to :user
  belongs_to :activity, polymorphic: true

  index [:user_id, :activity_id, :activity_type], :background => true, :unique => true

  field :last_access_time, :type => Time
  # last_access_times just here for history, not used
  field :last_access_times, :type => Array, :default => []
end

activity = SiteActivity.find_or_initialize_by(:user_id => current_user.id,
               :activity_id => post.id, :activity_type => post.class)
time = Time.now.utc
activity.last_access_time = time
activity.last_access_times << time
activity.save