如何缓存按评分排序的前 N 个帖子?
How to cache top N posts ordered by rating?
我正在写一个 Rails 5 JSON API.
我有一项操作 returns top N 篇博文 基于 平均评分。为了实现低响应时间,我对数据库进行了非规范化,这样 posts
就有一个 average_rating
列。
我也像这样缓存每个查询:
# posts_controller.rb
def top
quantity = params[:quantity]
if quantity.to_i > 0
render json: {
posts: cached_top_posts(quantity)
}, status: :ok
else
render json: '', status: :unprocessable_entity
end
end
def cached_top_posts(quantity)
Rails.cache.fetch(['top', quantity], expires_in: 1.hour) do
Post.limit(quantity).as_json(only: [:title, :content, :average_rating])
end
end
(按 average_rating
排序在模型本身中)
我知道这远非最佳。
虽然它在请求相同数量的帖子时大大缩短了响应时间,但如果它已经缓存了前 1000 个帖子,那么它会更好 缓存 100 个帖子,而是从缓存的 1000.
中获取 前 100 个帖子
实现此目的的好方法是什么?
嗯,好好睡了一觉,脑子里就浮现出一个简单的结论。
这里是:
# posts_controller.rb
def cached_top_posts(quantity)
data = Rails.cache.read('top_posts')
if data.nil? || data[:quantity] < quantity
data = {
:quantity => quantity,
:posts => Post.limit(quantity).as_json(only: [:title, :content, :average_rating])
}
Rails.cache.write('top_posts', data, expires_in: 1.hour)
end
data[:posts][0...quantity]
end
我正在写一个 Rails 5 JSON API.
我有一项操作 returns top N 篇博文 基于 平均评分。为了实现低响应时间,我对数据库进行了非规范化,这样 posts
就有一个 average_rating
列。
我也像这样缓存每个查询:
# posts_controller.rb
def top
quantity = params[:quantity]
if quantity.to_i > 0
render json: {
posts: cached_top_posts(quantity)
}, status: :ok
else
render json: '', status: :unprocessable_entity
end
end
def cached_top_posts(quantity)
Rails.cache.fetch(['top', quantity], expires_in: 1.hour) do
Post.limit(quantity).as_json(only: [:title, :content, :average_rating])
end
end
(按 average_rating
排序在模型本身中)
我知道这远非最佳。
虽然它在请求相同数量的帖子时大大缩短了响应时间,但如果它已经缓存了前 1000 个帖子,那么它会更好 缓存 100 个帖子,而是从缓存的 1000.
中获取 前 100 个帖子实现此目的的好方法是什么?
嗯,好好睡了一觉,脑子里就浮现出一个简单的结论。
这里是:
# posts_controller.rb
def cached_top_posts(quantity)
data = Rails.cache.read('top_posts')
if data.nil? || data[:quantity] < quantity
data = {
:quantity => quantity,
:posts => Post.limit(quantity).as_json(only: [:title, :content, :average_rating])
}
Rails.cache.write('top_posts', data, expires_in: 1.hour)
end
data[:posts][0...quantity]
end