sql >> Base de Datos >  >> NoSQL >> MongoDB

Manera eficiente de almacenar datos en MongoDB:documentos incrustados frente a documentos individuales

Sería mejor usar el primer enfoque (documentos individuales) y usar una colección limitada si es posible, ya que no desea tener una colección en rápido crecimiento (mongoid tendrá soporte para colecciones limitadas en 2.2, que estaría disponible este fin de semana I supongo).

El segundo enfoque (documentos incrustados), primero deberá obtener el documento raíz para el usuario y luego recorrer la matriz en la aplicación para encontrar la actividad relacionada con la publicación que está buscando. Mongoid puede hacer que parezca que todo se hace en db debido a la similitud de la sintaxis para encontrar un documento incrustado, pero en realidad está iterando la matriz.

Como ya tiene el id_usuario, el id_actividad y el tipo_actividad antes de realizar una consulta, y no desea que la lista completa de actividades para el usuario se recupere de la base de datos cuando busca una actividad en particular, preferiré el primer caso. Habría muchos menos cálculos (búsquedas) en la aplicación y habrá mucho menos tráfico de red.

Con el enfoque de documentos individuales, sería genial si también crea un índice único en user_id, activity_id, activity_type. Le ayudará a contener la cantidad de documentos. Puede tener la validación de unicidad (consulta adicional), pero eso sería en su mayoría innecesario si tiene el índice único. El único beneficio de la validación será un error de validación si hay duplicados, pero el índice ignorará las entradas duplicadas en silencio a menos que persista en modo seguro.

En caso de que también desee que se conserve la actividad histórica del sitio, puede tener la estructura como:

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