search: optimize counting posts for fav: and pool: searches.
Optimize counting the number of posts returned by fav:<name> and pool:<name> searches. Use cached counts to avoid slow count(*) queries for users with lots of favorites.
This commit is contained in:
@@ -917,6 +917,20 @@ class PostQueryBuilder
|
|||||||
Tag.find_by(name: tags.first.name).try(:post_count)
|
Tag.find_by(name: tags.first.name).try(:post_count)
|
||||||
elsif is_metatag?(:rating)
|
elsif is_metatag?(:rating)
|
||||||
estimated_row_count
|
estimated_row_count
|
||||||
|
elsif is_metatag?(:pool) || is_metatag?(:ordpool)
|
||||||
|
name = find_metatag(:pool, :ordpool)
|
||||||
|
Pool.find_by_name(name)&.post_count || 0
|
||||||
|
elsif is_metatag?(:fav) || is_metatag?(:ordfav)
|
||||||
|
name = find_metatag(:fav, :ordfav)
|
||||||
|
user = User.find_by_name(name)
|
||||||
|
|
||||||
|
if user.nil?
|
||||||
|
0
|
||||||
|
elsif Pundit.policy!(current_user, user).can_see_favorites?
|
||||||
|
user.favorite_count
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
FactoryBot.define do
|
FactoryBot.define do
|
||||||
factory(:favorite)
|
factory(:favorite) do
|
||||||
|
user
|
||||||
|
post
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1190,9 +1190,34 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
should "return the correct cached count for a pool:<id> search" do
|
should "return the correct cached count for a pool:<id> search" do
|
||||||
build(:tag, name: "pool:1234", post_count: -100).save(validate: false)
|
pool = create(:pool, post_ids: [1, 2, 3])
|
||||||
|
|
||||||
|
build(:tag, name: "pool:#{pool.id}", post_count: -100).save(validate: false)
|
||||||
PostQueryBuilder.new("pool:1234").set_cached_count(100)
|
PostQueryBuilder.new("pool:1234").set_cached_count(100)
|
||||||
assert_fast_count(100, "pool:1234")
|
|
||||||
|
assert_fast_count(3, "pool:#{pool.id}")
|
||||||
|
assert_fast_count(3, "pool:#{pool.name}")
|
||||||
|
end
|
||||||
|
|
||||||
|
should "return the correct favorite count for a fav:<name> search" do
|
||||||
|
fav = create(:favorite)
|
||||||
|
fav.user.update!(favorite_count: 1)
|
||||||
|
|
||||||
|
assert_fast_count(1, "fav:#{fav.user.name}")
|
||||||
|
assert_fast_count(1, "ordfav:#{fav.user.name}")
|
||||||
|
end
|
||||||
|
|
||||||
|
should "return the correct favorite count for a fav:<name> search for a user with private favorites" do
|
||||||
|
fav = create(:favorite)
|
||||||
|
fav.user.update!(favorite_count: 1, enable_private_favorites: true)
|
||||||
|
|
||||||
|
assert_fast_count(0, "fav:#{fav.user.name}")
|
||||||
|
assert_fast_count(0, "ordfav:#{fav.user.name}")
|
||||||
|
end
|
||||||
|
|
||||||
|
should "return the correct favorite count for a fav:<name> search for a nonexistent user" do
|
||||||
|
assert_fast_count(0, "fav:doesnotexist")
|
||||||
|
assert_fast_count(0, "ordfav:doesnotexist")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user