PERF: only use fulltext when searching for a user (I checked, it's enough)

This commit is contained in:
Régis Hanol 2015-11-04 23:04:37 +01:00
parent abeac7f681
commit 7e255a151b
2 changed files with 11 additions and 13 deletions

View File

@ -39,8 +39,7 @@ class UserSearch
query = Search.ts_query(@term, "simple") query = Search.ts_query(@term, "simple")
users = users.includes(:user_search_data) users = users.includes(:user_search_data)
.references(:user_search_data) .references(:user_search_data)
.where("username_lower LIKE :term_like OR user_search_data.search_data @@ #{query}", .where("user_search_data.search_data @@ #{query}")
term: @term, term_like: @term_like)
.order(User.sql_fragment("CASE WHEN username_lower LIKE ? THEN 0 ELSE 1 END ASC", @term_like)) .order(User.sql_fragment("CASE WHEN username_lower LIKE ? THEN 0 ELSE 1 END ASC", @term_like))
else else
users = users.where("username_lower LIKE :term_like", term_like: @term_like) users = users.where("username_lower LIKE :term_like", term_like: @term_like)
@ -56,36 +55,35 @@ class UserSearch
# 1. exact username matches # 1. exact username matches
if @term.present? if @term.present?
scoped_users.where(username_lower: @term.downcase) scoped_users.where(username_lower: @term.downcase)
.limit(@limit)
.pluck(:id) .pluck(:id)
.each{|id| users << id} .each { |id| users << id }
end end
return users.to_a if users.length == @limit return users.to_a if users.length >= @limit
# 2. in topic # 2. in topic
if @topic_id if @topic_id
filtered_by_term_users.where('users.id in (SELECT p.user_id FROM posts p WHERE topic_id = ?)', @topic_id) filtered_by_term_users.where('users.id IN (SELECT p.user_id FROM posts p WHERE topic_id = ?)', @topic_id)
.order('last_seen_at DESC') .order('last_seen_at DESC')
.limit(@limit - users.length) .limit(@limit - users.length)
.pluck(:id) .pluck(:id)
.each{|id| users << id} .each { |id| users << id }
end end
return users.to_a if users.length == @limit return users.to_a if users.length >= @limit
# 3. global matches # 3. global matches
filtered_by_term_users.order('last_seen_at DESC') filtered_by_term_users.order('last_seen_at DESC')
.limit(@limit - users.length) .limit(@limit - users.length)
.pluck(:id) .pluck(:id)
.each{|id| users << id} .each { |id| users << id }
users.to_a users.to_a
end end
def search def search
ids = search_ids ids = search_ids
return User.where("0=1") if ids.empty? return User.where("0=1") if ids.empty?
@ -93,7 +91,6 @@ class UserSearch
FROM unnest('{#{ids.join(",")}}'::int[]) FROM unnest('{#{ids.join(",")}}'::int[])
) x on uid = users.id") ) x on uid = users.id")
.order("rn") .order("rn")
end end
end end

View File

@ -382,11 +382,12 @@ class Search
return if SiteSetting.hide_user_profiles_from_public && !@guardian.user return if SiteSetting.hide_user_profiles_from_public && !@guardian.user
users = User.includes(:user_search_data) users = User.includes(:user_search_data)
.where("active = true AND user_search_data.search_data @@ #{ts_query("simple")}") .references(:user_search_data)
.where("active = TRUE")
.where("user_search_data.search_data @@ #{ts_query("simple")}")
.order("CASE WHEN username_lower = '#{@original_term.downcase}' THEN 0 ELSE 1 END") .order("CASE WHEN username_lower = '#{@original_term.downcase}' THEN 0 ELSE 1 END")
.order("last_posted_at DESC") .order("last_posted_at DESC")
.limit(@limit) .limit(@limit)
.references(:user_search_data)
users.each do |user| users.each do |user|
@results.add(user) @results.add(user)