Ruby on rails 在MongoDB中存储数据的有效方法:嵌入式文档与单个文档
我存储用户活动数据:当用户访问当前文章、主题或个人消息时,显示他脱机时添加了多少新评论和消息Ruby on rails 在MongoDB中存储数据的有效方法:嵌入式文档与单个文档,ruby-on-rails,ruby,performance,mongodb,mongoid,Ruby On Rails,Ruby,Performance,Mongodb,Mongoid,我存储用户活动数据:当用户访问当前文章、主题或个人消息时,显示他脱机时添加了多少新评论和消息 class SiteActivity include Mongoid::Document include Mongoid::Timestamps belongs_to :user belons_to :activity, polymorphic: true end 在这种情况下,我为每个文档存储一条记录 另一种选择是使用嵌入式文档,因此所有用户活动都将存储在一个文档中: class S
class SiteActivity
include Mongoid::Document
include Mongoid::Timestamps
belongs_to :user
belons_to :activity, polymorphic: true
end
在这种情况下,我为每个文档存储一条记录
另一种选择是使用嵌入式文档,因此所有用户活动都将存储在一个文档中:
class SiteActivity
include Mongoid::Document
belongs_to :user
embeds_many :user_activities
validates :user_id, uniqueness: true
end
class UserActivity
include Mongoid::Document
include Mongoid::Timestamps
embedded_in :site_activity
belongs_to :activity, polymorphic: true
end
因此,现在我不需要搜索所有SiteActivities(许多记录),但我可以为当前用户获取一个user\u activity
,并通过嵌入的文档找到我需要的活动
哪种方式存储和搜索数据更有效?
我的普通用例是:
我有一个用户和一篇文章,所以我正在获取带有此数据的site_活动,以查看此用户上次访问文章的日期
我的第一个选择是:
activity = SiteActivity.where(user_id: current_user.id, activity_id: post.id, activity_type: post.class)
第二
user_activity = SiteActivity.where(user_id: current_user.id)
activity = user_activity.user_activities.where(activity_id: post.id, activity_type: post.class)
如果可能的话,最好使用第一种方法(单个文档)并使用封顶集合,因为您不想拥有快速增长的集合(mongoid将在2.2中支持封顶集合,我想这将在本周末推出) 第二种方法(嵌入式文档),您需要首先为用户获取根文档,然后遍历应用程序中的数组,以查找与您正在查找的帖子相关的活动。由于在查找嵌入文档时语法的相似性,Mongoid可能会使它看起来像是在db中完成了所有事情,但它实际上是在迭代数组 由于在进行查询之前,您已经有了user\u id、activity\u id和activity\u type,并且在查找特定活动时,您不希望从db检索用户的整个活动列表,因此我更喜欢第一种情况。应用程序中的计算(搜索)会少得多,网络流量也会少得多 使用单个文档的方法,如果您还可以在用户id、活动id和活动类型上创建一个唯一的索引,那就太好了。它将帮助您包含文档的数量。您可以进行唯一性验证(额外的查询),但如果您有唯一索引,那么这将是不必要的。如果存在重复项,验证的唯一好处是验证错误,但除非您坚持使用安全模式,否则索引将自动忽略重复项 如果您还希望保留历史遗址活动,则可以采用如下结构:
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
类站点活动
include Mongoid::Document
包含Mongoid::时间戳
属于:用户
属于:活动,多态性:true
索引[:user\u id,:activity\u id,:activity\u type],:background=>true,:unique=>true
字段:上次访问时间,:type=>time
#上次访问时间仅用于历史记录,未使用
字段:上次访问次数,:type=>Array,:default=>[]
结束
activity=SiteActivity.find_或_initialize_by(:user_id=>current_user.id,
:activity\u id=>post.id,:activity\u type=>post.class)
时间=time.now.utc
activity.last\u access\u time=时间
activity.last_access_times昨天似乎讨论过类似的话题。
看看,也许会有帮助。谢谢。这看起来像是你说服了我:)在我的例子中,我使用Mongoid::Timestamps
作为最后一次访问时间来进行extracetupdated\u at
因为这是相同的东西是的,它的行为应该类似。