1

所以我正在开发一个 Rails 应用程序,并且我正在对提要进行分页。当我这样做时,我想知道我是否以正确的方式进行操作,因为我的加载时间超过 1500 毫秒。我的代码是:

stories = Story.feed
@stories = Kaminari.paginate_array(stories).page(params[:page]).per(params[:pageSize])

我对此有几个问题:

  1. 我应该分页Story.feed,还是有某种方法只返回我需要的一些故事?
  2. 这个加载时间正常吗?
  3. 我还可以做些什么来优化它

(另外,Story.feed 返回一个故事对象数组。代码在这里:

  def self.feed
    rawStories = Story.includes([:likes, :viewers, :user, :storyblocks]).all
    newFeaturedStories = rawStories.where(:featured => true).where(:updated_at.gte => (Date.today - 3)).desc(:created_at).entries
    normalStories = rawStories.not_in(:featured => true, :or => [:updated_at.gte => (Date.today - 3)]).desc(:created_at).entries
    newFeaturedStories.entries.concat(normalStories.entries)
  end

我正在使用 mongoid 和 mongodb

4

3 回答 3

0

我怀疑当你调用Kaminari.paginate_array一个时ActiveRecord::Relation,它会导致整个结果集从数据库中获取并加载到内存中,类似于调用Model.all.to_a

为了避免这种情况,我首先要找到一种方法来Story.feed转换为范围,而不是类方法。从表面上看,它们看起来是一样的——差异是微妙但深刻的。请参阅Active Record 范围与类方法

接下来,paginate_array放弃链式 Kaminaripage()per()范围。

例如(您的简化版):

class Article < ActiveRecord::Base

  scope :featured,    -> { where(featured: true) }
  scope :last_3_days, -> { where(:updated_at.gte => (Date.today - 3)).desc(:created_at) }
  scope :feed,        -> { featured.last_3_days }

然后只需通过以下方式进行分页:

Article.feed.per(page_size).page(page)

这样做的最大优点是 Kaminari 可以链接到生成的 SQL 中插入正确的LIMITandOFFSET子句,从而减少返回的结果集的大小,只返回需要显示的内容,而不是返回每个匹配的记录。

于 2013-07-19T07:08:33.330 回答
0

问题是您从数组中的 db 获取所有提要,这需要很长时间。

我建议你使用这个伟大的 gemany_of的查询。

从那里,做:

def self.feed_stories
  newFeaturedStories = Story.where(:featured => true).where(:updated_at.gte => (Date.today - 3.days))
  normalStories      = Story.not_in(:featured => true, :or => [:updated_at.gte => (Date.today - 3.days)])
  Story.includes([:likes, :viewers, :user, :storyblocks]).any_of(newFeaturedStories, normalStories).desc(:created_at)
end

然后分页:

selected_stories = Story.feed_stories.per(page_size).page(page)

不太了解你的内容,entries但现在得到它们。

总结一下:做一个独特的分页数据库查询的想法。

于 2013-07-19T07:13:11.550 回答
-1

我认为 Will Paginate 会在这里帮助你 -> mislav/will_paginate。从那里您可以简单地给您的控制器操作 .per_page(20) 例如,在 20 个对象之后(您可以定义对象,请参阅 wiki)会有分页

于 2013-07-19T05:15:29.640 回答