我目前在Rails应用程序中有以下控制器方法:
def index
@entries = []
@entries << QuickPost.where(:user_id.in => current_user.followees.map(&:ff_id) << current_user.id)
@entries << Infographic.where(:user_id.in => current_user.followees.map(&:ff_id) << current_user.id)
@entries.flatten!.sort!{ |a,b| b.created_at <=> a.created_at }
@entries = Kaminari.paginate_array(@entries).page(params[:page]).per(10)
end
我意识到这非常低效,所以我正在寻找一种更好的方法来实现相同的目标,但我是MongoDB的新手,并想知道最佳解决方案是什么。
有没有办法在MongoDB中跨两个集合进行排序的limit()查询或MapReduce函数?我猜不会有,但在这种情况下肯定会省下很多努力!
我目前认为我有两种选择:
我有没有忽视的选择?我是否过度使用上述选项?这类情况有哪些最佳实践?
任何信息都会非常感激,到目前为止我真的很喜欢MongoDB,并且希望避免将来陷入这样的陷阱。感谢。
答案 0 :(得分:2)
继承解决方案很好,但是当继承的模型接近时。 例如:
class Post < BasePost
field :body, type: String
end
class QuickPost < BasePost
end
class BasePost
field :title, type: String
field :created_at, type: Time
end
但是当模型增长或者太不同时,你的第二个解决方案会更好。
class Activity
include Mongoid::Document
paginates_per 20
field :occurred_at, :type => Time, :default => nil
validates_presence_of :occurred_at
belongs_to :user
belongs_to :quick_post
belongs_to :infographic
default_scope desc(:occurred_at)
end
,例如:
class QuickPost
include Mongoid::Document
has_one :activity, :dependent => :destroy
end
依赖性破坏会在QuickPost被销毁时销毁活动。你可以使用has_many和adapt。
要创建活动,您可以创建一个观察者:
class ActivityObserver < Mongoid::Observer
observe :quick_post, :infographic
def after_save(record)
if record.is_a? QuickPost
if record.new_record?
activity = record.build_activity
activity.user = record.user
# stuff when it is new
else
activity = record.activity
end
activity.occurred_at = record.occurred_at
# common stuff
activity.save
end
end
end