MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Modo efficiente per archiviare i dati in MongoDB:documenti incorporati rispetto a singoli documenti

Sarebbe meglio utilizzare il primo approccio (documenti individuali) e utilizzare una raccolta limitata, se possibile, poiché non si desidera avere una raccolta in rapida crescita (mongoid avrà il supporto per le raccolte limitate nella 2.2, che uscirà questo fine settimana I indovina).

Il secondo approccio (documenti incorporati), dovrai prima recuperare il documento radice per l'utente e quindi attraversare l'array nell'applicazione per trovare l'attività relativa al post che stai cercando. Mongoid può far sembrare che tutto sia fatto in db a causa della somiglianza della sintassi nella ricerca di un documento incorporato, ma sta davvero iterando l'array.

Dato che hai già user_id, activity_id e activity_type prima di fare una query e non vorresti che l'intero elenco di attività per l'utente venisse recuperato da db quando stai cercando una particolare attività, preferirò il primo caso. Ci sarebbero molti meno calcoli nell'applicazione e ci sarebbe molto meno traffico di rete.

Con l'approccio dei singoli documenti, sarebbe fantastico creare anche un indice univoco su user_id, activity_id, activity_type. Ti aiuterà a contenere il numero di documenti. Puoi avere la convalida dell'unicità (query extra), ma ciò sarebbe per lo più non necessario se disponi dell'indice univoco. L'unico vantaggio della convalida sarà un errore di convalida se sono presenti duplicati, ma l'indice ignorerà le voci duplicate in modo invisibile, a meno che tu non persista in modalità provvisoria.

Nel caso in cui desideri che anche l'attività storica del sito venga mantenuta, puoi avere la struttura come:

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