Het zou beter zijn om de eerste benadering te gebruiken (individuele documenten) en indien mogelijk een afgetopte verzameling te gebruiken, omdat u geen snelgroeiende verzameling wilt hebben (mongoid zal ondersteuning hebben voor afgetopte verzamelingen in 2.2, die dit weekend zou verschijnen. raden).
Bij de tweede benadering (ingesloten documenten), moet u eerst het hoofddocument voor de gebruiker ophalen en vervolgens de array in de toepassing doorkruisen om de activiteit te vinden die verband houdt met de post waarnaar u op zoek bent. Mongoid kan het laten lijken alsof alles in db wordt gedaan vanwege de gelijkenis van de syntaxis bij het vinden van een ingesloten document, maar het is echt een iteratie van de array.
Omdat je de user_id, activity_id en activity_type al hebt voordat je een query maakt, en je niet wilt dat de hele lijst met activiteiten voor de gebruiker wordt opgehaald uit db wanneer je op zoek bent naar een bepaalde activiteit, geef ik de voorkeur aan het eerste geval. Er zouden veel minder berekeningen (zoeken) in de applicatie zijn en er zal veel minder netwerkverkeer zijn.
Met de benadering van individuele documenten zou het geweldig zijn als u ook een unieke index maakt op user_id, activity_id, activity_type. Het zal u helpen het aantal documenten te bevatten. U kunt de uniciteitsvalidatie (extra query) hebben, maar dat zou meestal niet nodig zijn als u de unieke index hebt. Het enige voordeel van validatie is een validatiefout als er duplicaten zijn, maar index negeert dubbele vermeldingen stilletjes, tenzij je in de veilige modus blijft.
Als u ook wilt dat de historische site-activiteit behouden blijft, kunt u de structuur als volgt hebben:
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