クエリ・パフォーマンスの改善(#258) (#259)
#258 #258 #258 Co-authored-by: miteruzo <miteruzo@naver.com> Reviewed-on: #259
This commit was merged in pull request #259.
This commit is contained in:
@@ -6,11 +6,11 @@ class NicoTagsController < ApplicationController
|
|||||||
cursor = params[:cursor].presence
|
cursor = params[:cursor].presence
|
||||||
|
|
||||||
q = Tag.nico_tags
|
q = Tag.nico_tags
|
||||||
.includes(:tag_name, linked_tags: :tag_name)
|
.includes(:tag_name, tag_name: :wiki_page, linked_tags: { tag_name: :wiki_page })
|
||||||
.order(updated_at: :desc)
|
.order(updated_at: :desc)
|
||||||
q = q.where('tags.updated_at < ?', Time.iso8601(cursor)) if cursor
|
q = q.where('tags.updated_at < ?', Time.iso8601(cursor)) if cursor
|
||||||
|
|
||||||
tags = q.limit(limit + 1)
|
tags = q.limit(limit + 1).to_a
|
||||||
|
|
||||||
next_cursor = nil
|
next_cursor = nil
|
||||||
if tags.size > limit
|
if tags.size > limit
|
||||||
|
|||||||
@@ -17,16 +17,17 @@ class PostsController < ApplicationController
|
|||||||
'posts.created_at)'
|
'posts.created_at)'
|
||||||
q =
|
q =
|
||||||
filtered_posts
|
filtered_posts
|
||||||
.preload(tags: :tag_name)
|
.preload(tags: { tag_name: :wiki_page })
|
||||||
.with_attached_thumbnail
|
.with_attached_thumbnail
|
||||||
.select("posts.*, #{ sort_sql } AS sort_ts")
|
.select("posts.*, #{ sort_sql } AS sort_ts")
|
||||||
.order(Arel.sql("#{ sort_sql } DESC"))
|
.order(Arel.sql("#{ sort_sql } DESC"))
|
||||||
posts = (
|
posts =
|
||||||
if cursor
|
if cursor
|
||||||
q.where("#{ sort_sql } < ?", Time.iso8601(cursor)).limit(limit + 1)
|
q.where("#{ sort_sql } < ?", Time.iso8601(cursor)).limit(limit + 1)
|
||||||
else
|
else
|
||||||
q.limit(limit).offset(offset)
|
q.limit(limit).offset(offset)
|
||||||
end).to_a
|
end
|
||||||
|
.to_a
|
||||||
|
|
||||||
next_cursor = nil
|
next_cursor = nil
|
||||||
if cursor && posts.length > limit
|
if cursor && posts.length > limit
|
||||||
@@ -52,7 +53,9 @@ class PostsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def random
|
def random
|
||||||
post = filtered_posts.preload(tags: :tag_name).order('RAND()').first
|
post = filtered_posts.preload(tags: { tag_name: :wiki_page })
|
||||||
|
.order('RAND()')
|
||||||
|
.first
|
||||||
return head :not_found unless post
|
return head :not_found unless post
|
||||||
|
|
||||||
viewed = current_user&.viewed?(post) || false
|
viewed = current_user&.viewed?(post) || false
|
||||||
@@ -64,7 +67,7 @@ class PostsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
post = Post.includes(tags: :tag_name).find(params[:id])
|
post = Post.includes(tags: { tag_name: :wiki_page }).find(params[:id])
|
||||||
return head :not_found unless post
|
return head :not_found unless post
|
||||||
|
|
||||||
viewed = current_user&.viewed?(post) || false
|
viewed = current_user&.viewed?(post) || false
|
||||||
@@ -151,7 +154,7 @@ class PostsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def changes
|
def changes
|
||||||
id = params[:id]
|
id = params[:id].presence
|
||||||
page = (params[:page].presence || 1).to_i
|
page = (params[:page].presence || 1).to_i
|
||||||
limit = (params[:limit].presence || 20).to_i
|
limit = (params[:limit].presence || 20).to_i
|
||||||
|
|
||||||
@@ -162,30 +165,34 @@ class PostsController < ApplicationController
|
|||||||
|
|
||||||
pts = PostTag.with_discarded
|
pts = PostTag.with_discarded
|
||||||
pts = pts.where(post_id: id) if id.present?
|
pts = pts.where(post_id: id) if id.present?
|
||||||
pts = pts.includes(:post, { tag: :tag_name }, :created_user, :deleted_user)
|
pts = pts.includes(:post, :created_user, :deleted_user,
|
||||||
|
tag: { tag_name: :wiki_page })
|
||||||
|
|
||||||
events = []
|
events = []
|
||||||
pts.each do |pt|
|
pts.each do |pt|
|
||||||
|
tag = pt.tag.as_json(only: [:id, :category], methods: [:name, :has_wiki])
|
||||||
|
post = pt.post
|
||||||
|
|
||||||
events << Event.new(
|
events << Event.new(
|
||||||
post: pt.post,
|
post:,
|
||||||
tag: pt.tag.as_json(only: [:id, :category], methods: [:name, :has_wiki]),
|
tag:,
|
||||||
user: pt.created_user && { id: pt.created_user.id, name: pt.created_user.name },
|
user: pt.created_user && { id: pt.created_user.id, name: pt.created_user.name },
|
||||||
change_type: 'add',
|
change_type: 'add',
|
||||||
timestamp: pt.created_at)
|
timestamp: pt.created_at)
|
||||||
|
|
||||||
if pt.discarded_at
|
if pt.discarded_at
|
||||||
events << Event.new(
|
events << Event.new(
|
||||||
post: pt.post,
|
post:,
|
||||||
tag: pt.tag.as_json(only: [:id, :category], methods: [:name, :has_wiki]),
|
tag:,
|
||||||
user: pt.deleted_user && { id: pt.deleted_user.id, name: pt.deleted_user.name },
|
user: pt.deleted_user && { id: pt.deleted_user.id, name: pt.deleted_user.name },
|
||||||
change_type: 'remove',
|
change_type: 'remove',
|
||||||
timestamp: pt.discarded_at)
|
timestamp: pt.discarded_at)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
events.sort_by!(&:timestamp)
|
events.sort_by!(&:timestamp)
|
||||||
events.reverse!
|
events.reverse!
|
||||||
|
|
||||||
render json: { changes: events.slice(offset, limit).as_json, count: events.size }
|
render json: { changes: (events.slice(offset, limit) || []).as_json, count: events.size }
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@@ -4,10 +4,14 @@ class TagsController < ApplicationController
|
|||||||
|
|
||||||
tags =
|
tags =
|
||||||
if post_id.present?
|
if post_id.present?
|
||||||
Tag.joins(:posts).where(posts: { id: post_id })
|
Tag.joins(:posts, :tag_name)
|
||||||
else
|
else
|
||||||
Tag.all
|
Tag.joins(:tag_name)
|
||||||
end
|
end
|
||||||
|
.includes(:tag_name, tag_name: :wiki_page)
|
||||||
|
if post_id.present?
|
||||||
|
tags = tags.where(posts: { id: post_id })
|
||||||
|
end
|
||||||
|
|
||||||
render json: tags.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki])
|
render json: tags.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki])
|
||||||
end
|
end
|
||||||
@@ -33,7 +37,8 @@ class TagsController < ApplicationController
|
|||||||
matched_alias_by_tag_name_id[canonical_id] ||= alias_name
|
matched_alias_by_tag_name_id[canonical_id] ||= alias_name
|
||||||
end
|
end
|
||||||
|
|
||||||
base = Tag.joins(:tag_name).includes(:tag_name)
|
base = Tag.joins(:tag_name)
|
||||||
|
.includes(:tag_name, tag_name: :wiki_page)
|
||||||
base = base.where('tags.post_count > 0') if present_only
|
base = base.where('tags.post_count > 0') if present_only
|
||||||
|
|
||||||
canonical_hit =
|
canonical_hit =
|
||||||
@@ -58,7 +63,9 @@ class TagsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
tag = Tag.find_by(id: params[:id])
|
tag = Tag.joins(:tag_name)
|
||||||
|
.includes(:tag_name, tag_name: :wiki_page)
|
||||||
|
.find_by(id: params[:id])
|
||||||
if tag
|
if tag
|
||||||
render json: tag.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki])
|
render json: tag.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki])
|
||||||
else
|
else
|
||||||
@@ -70,7 +77,9 @@ class TagsController < ApplicationController
|
|||||||
name = params[:name].to_s.strip
|
name = params[:name].to_s.strip
|
||||||
return head :bad_request if name.blank?
|
return head :bad_request if name.blank?
|
||||||
|
|
||||||
tag = Tag.joins(:tag_name).includes(:tag_name).find_by(tag_names: { name: })
|
tag = Tag.joins(:tag_name)
|
||||||
|
.includes(:tag_name, tag_name: :wiki_page)
|
||||||
|
.find_by(tag_names: { name: })
|
||||||
if tag
|
if tag
|
||||||
render json: tag.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki])
|
render json: tag.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki])
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ class WikiPagesController < ApplicationController
|
|||||||
|
|
||||||
def index
|
def index
|
||||||
title = params[:title].to_s.strip
|
title = params[:title].to_s.strip
|
||||||
return render json: WikiPage.all.as_json(methods: [:title]) if title.blank?
|
if title.blank?
|
||||||
|
return render json: WikiPage.joins(:tag_name)
|
||||||
|
.includes(:tag_name)
|
||||||
|
.as_json(methods: [:title])
|
||||||
|
end
|
||||||
|
|
||||||
q = WikiPage.joins(:tag_name).includes(:tag_name)
|
q = WikiPage.joins(:tag_name).includes(:tag_name)
|
||||||
.where('tag_names.name LIKE ?', "%#{ WikiPage.sanitize_sql_like(title) }%")
|
.where('tag_names.name LIKE ?', "%#{ WikiPage.sanitize_sql_like(title) }%")
|
||||||
@@ -11,7 +15,9 @@ class WikiPagesController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
page = WikiPage.find_by(id: params[:id])
|
page = WikiPage.joins(:tag_name)
|
||||||
|
.includes(:tag_name)
|
||||||
|
.find_by(id: params[:id])
|
||||||
render_wiki_page_or_404 page
|
render_wiki_page_or_404 page
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -19,7 +25,7 @@ class WikiPagesController < ApplicationController
|
|||||||
title = params[:title].to_s.strip
|
title = params[:title].to_s.strip
|
||||||
page = WikiPage.joins(:tag_name)
|
page = WikiPage.joins(:tag_name)
|
||||||
.includes(:tag_name)
|
.includes(:tag_name)
|
||||||
.find_by(tag_names: { name: title })
|
.find_by(tag_name: { name: title })
|
||||||
render_wiki_page_or_404 page
|
render_wiki_page_or_404 page
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -47,7 +53,7 @@ class WikiPagesController < ApplicationController
|
|||||||
from = params[:from].presence
|
from = params[:from].presence
|
||||||
to = params[:to].presence
|
to = params[:to].presence
|
||||||
|
|
||||||
page = WikiPage.find(id)
|
page = WikiPage.joins(:tag_name).includes(:tag_name).find(id)
|
||||||
|
|
||||||
from_rev = from && page.wiki_revisions.find(from)
|
from_rev = from && page.wiki_revisions.find(from)
|
||||||
to_rev = to ? page.wiki_revisions.find(to) : page.current_revision
|
to_rev = to ? page.wiki_revisions.find(to) : page.current_revision
|
||||||
@@ -131,7 +137,9 @@ class WikiPagesController < ApplicationController
|
|||||||
|
|
||||||
def changes
|
def changes
|
||||||
id = params[:id].presence
|
id = params[:id].presence
|
||||||
q = WikiRevision.includes(:wiki_page, :created_user).order(id: :desc)
|
q = WikiRevision.joins(wiki_page: :tag_name)
|
||||||
|
.includes(:created_user, wiki_page: :tag_name)
|
||||||
|
.order(id: :desc)
|
||||||
q = q.where(wiki_page_id: id) if id
|
q = q.where(wiki_page_id: id) if id
|
||||||
|
|
||||||
render json: q.limit(200).map { |rev|
|
render json: q.limit(200).map { |rev|
|
||||||
@@ -139,7 +147,7 @@ class WikiPagesController < ApplicationController
|
|||||||
pred: rev.base_revision_id,
|
pred: rev.base_revision_id,
|
||||||
succ: nil,
|
succ: nil,
|
||||||
wiki_page: { id: rev.wiki_page_id, title: rev.wiki_page.title },
|
wiki_page: { id: rev.wiki_page_id, title: rev.wiki_page.title },
|
||||||
user: { id: rev.created_user.id, name: rev.created_user.name },
|
user: rev.created_user && { id: rev.created_user.id, name: rev.created_user.name },
|
||||||
kind: rev.kind,
|
kind: rev.kind,
|
||||||
message: rev.message,
|
message: rev.message,
|
||||||
timestamp: rev.created_at }
|
timestamp: rev.created_at }
|
||||||
|
|||||||
@@ -30,13 +30,15 @@ class Post < ApplicationRecord
|
|||||||
super(options).merge(thumbnail: nil)
|
super(options).merge(thumbnail: nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
def related(limit: nil)
|
def related limit: nil
|
||||||
ids = post_similarities.select(:target_post_id).order(cos: :desc)
|
ids = post_similarities.order(cos: :desc)
|
||||||
ids = ids.limit(limit) if limit
|
ids = ids.limit(limit) if limit
|
||||||
ids = ids.pluck(:target_post_id)
|
ids = ids.pluck(:target_post_id)
|
||||||
return [] if ids.empty?
|
return Post.none if ids.empty?
|
||||||
|
|
||||||
Post.where(id: ids).order(Arel.sql("FIELD(id, #{ ids.join(',') })"))
|
Post.where(id: ids)
|
||||||
|
.with_attached_thumbnail
|
||||||
|
.order(Arel.sql("FIELD(posts.id, #{ ids.join(',') })"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def resized_thumbnail!
|
def resized_thumbnail!
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ class Tag < ApplicationRecord
|
|||||||
has_many :tag_similarities, dependent: :delete_all
|
has_many :tag_similarities, dependent: :delete_all
|
||||||
|
|
||||||
belongs_to :tag_name
|
belongs_to :tag_name
|
||||||
|
delegate :wiki_page, to: :tag_name
|
||||||
|
|
||||||
delegate :name, to: :tag_name, allow_nil: true
|
delegate :name, to: :tag_name, allow_nil: true
|
||||||
validates :tag_name, presence: true
|
validates :tag_name, presence: true
|
||||||
|
|
||||||
@@ -56,7 +58,7 @@ class Tag < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def has_wiki
|
def has_wiki
|
||||||
tag_name&.wiki_page.present?
|
wiki_page.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.tagme
|
def self.tagme
|
||||||
|
|||||||
Reference in New Issue
Block a user