Fix queries count in fan_out antennas

This commit is contained in:
KMY 2023-04-26 11:23:54 +09:00
parent b527b68958
commit 9db152db38
5 changed files with 43 additions and 25 deletions

View file

@ -18,6 +18,8 @@
# min_reblogs :integer # min_reblogs :integer
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# min_emojis :integer
# keep_self_emoji :boolean default(TRUE), not null
# #
class AccountStatusesCleanupPolicy < ApplicationRecord class AccountStatusesCleanupPolicy < ApplicationRecord
include Redisable include Redisable

View file

@ -17,6 +17,9 @@
# updated_at :datetime not null # updated_at :datetime not null
# expires_at :datetime # expires_at :datetime
# with_media_only :boolean default(FALSE), not null # with_media_only :boolean default(FALSE), not null
# exclude_domains :jsonb
# exclude_accounts :jsonb
# exclude_tags :jsonb
# #
class Antenna < ApplicationRecord class Antenna < ApplicationRecord
include Expireable include Expireable
@ -86,7 +89,7 @@ class Antenna < ApplicationRecord
def keywords_raw=(raw) def keywords_raw=(raw)
keywords = raw.split(/\R/).filter { |r| r.present? && r.length >= 2 }.uniq keywords = raw.split(/\R/).filter { |r| r.present? && r.length >= 2 }.uniq
self[:keywords] = keywords self[:keywords] = keywords
self[:any_keywords] = !keywords.any? && !exclude_keywords&.any? self[:any_keywords] = !keywords.any?
end end
def exclude_keywords_raw def exclude_keywords_raw
@ -98,7 +101,6 @@ class Antenna < ApplicationRecord
def exclude_keywords_raw=(raw) def exclude_keywords_raw=(raw)
exclude_keywords = raw.split(/\R/).filter { |r| r.present? }.uniq exclude_keywords = raw.split(/\R/).filter { |r| r.present? }.uniq
self[:exclude_keywords] = exclude_keywords self[:exclude_keywords] = exclude_keywords
self[:any_keywords] = !keywords&.any? && !exclude_keywords.any?
end end
def tags_raw def tags_raw
@ -118,18 +120,19 @@ class Antenna < ApplicationRecord
end end
def exclude_tags_raw def exclude_tags_raw
antenna_tags.where(exclude: true).map(&:tag).map(&:name).join("\n") return '' if !exclude_tags.present?
Tag.where(id: exclude_tags).map(&:name).join("\n")
end end
def exclude_tags_raw=(raw) def exclude_tags_raw=(raw)
return if exclude_tags_raw == raw return if exclude_tags_raw == raw
tags = []
tag_names = raw.split(/\R/).filter { |r| r.present? }.map { |r| r.start_with?('#') ? r[1..-1] : r }.uniq tag_names = raw.split(/\R/).filter { |r| r.present? }.map { |r| r.start_with?('#') ? r[1..-1] : r }.uniq
antenna_tags.where(exclude: true).destroy_all
Tag.find_or_create_by_names(tag_names).each do |tag| Tag.find_or_create_by_names(tag_names).each do |tag|
antenna_tags.create!(tag: tag, exclude: true) tags << tag.id
end end
self[:exclude_tags] = tags
end end
def domains_raw def domains_raw
@ -149,18 +152,15 @@ class Antenna < ApplicationRecord
end end
def exclude_domains_raw def exclude_domains_raw
antenna_domains.where(exclude: true).map(&:name).join("\n") return '' if !exclude_domains.present?
exclude_domains.join("\n")
end end
def exclude_domains_raw=(raw) def exclude_domains_raw=(raw)
return if exclude_domains_raw == raw return if exclude_domains_raw == raw
domain_names = raw.split(/\R/).filter { |r| r.present? }.uniq domain_names = raw.split(/\R/).filter { |r| r.present? }.uniq
self[:exclude_domains] = domain_names
antenna_domains.where(exclude: true).destroy_all
domain_names.each do |domain|
antenna_domains.create!(name: domain, exclude: true)
end
end end
def accounts_raw def accounts_raw
@ -186,7 +186,8 @@ class Antenna < ApplicationRecord
end end
def exclude_accounts_raw def exclude_accounts_raw
antenna_accounts.where(exclude: true).map(&:account).map { |account| account.domain ? "@#{account.username}@#{account.domain}" : "@#{account.username}" }.join("\n") return '' if !exclude_accounts.present?
Account.where(id: exclude_accounts).map { |account| account.domain ? "@#{account.username}@#{account.domain}" : "@#{account.username}" }.join("\n")
end end
def exclude_accounts_raw=(raw) def exclude_accounts_raw=(raw)
@ -194,16 +195,15 @@ class Antenna < ApplicationRecord
account_names = raw.split(/\R/).filter { |r| r.present? }.map { |r| r.start_with?('@') ? r[1..-1] : r }.uniq account_names = raw.split(/\R/).filter { |r| r.present? }.map { |r| r.start_with?('@') ? r[1..-1] : r }.uniq
hit = false accounts = []
antenna_accounts.where(exclude: true).destroy_all
account_names.each do |name| account_names.each do |name|
username, domain = name.split('@') username, domain = name.split('@')
account = Account.find_by(username: username, domain: domain) account = Account.find_by(username: username, domain: domain)
if account.present? if account.present?
antenna_accounts.create!(account: account, exclude: true) accounts << account.id
hit = true
end end
end end
self[:exclude_accounts] = accounts
end end
end end

View file

@ -118,30 +118,34 @@ class FanOutOnWriteService < BaseService
def deliver_to_antennas! def deliver_to_antennas!
lists = [] lists = []
tag_ids = @status.tags.pluck(:id)
domain = @account.domain || Rails.configuration.x.local_domain
antennas = Antenna.availables antennas = Antenna.availables
antennas = antennas.left_joins(:antenna_accounts).where(any_accounts: true).or(Antenna.availables.left_joins(:antenna_accounts) .where(antenna_accounts: { exclude: false, account: @status.account })) antennas = antennas.left_joins(:antenna_accounts).where(any_accounts: true).or(Antenna.availables.left_joins(:antenna_accounts) .where(antenna_accounts: { exclude: false, account: @status.account }))
antennas = antennas.left_joins(:antenna_domains) .where(any_domains: true) .or(Antenna.availables.left_joins(:antenna_accounts).left_joins(:antenna_domains) .where(antenna_domains: { exclude: false, name: @status.account.domain })) antennas = antennas.left_joins(:antenna_domains) .where(any_domains: true) .or(Antenna.availables.left_joins(:antenna_accounts).left_joins(:antenna_domains) .where(antenna_domains: { exclude: false, name: @status.account.domain }))
antennas = antennas.left_joins(:antenna_tags) .where(any_tags: true) .or(Antenna.availables.left_joins(:antenna_accounts).left_joins(:antenna_domains).left_joins(:antenna_tags).where(antenna_tags: { exclude: false, tag: @status.tags })) antennas = antennas.left_joins(:antenna_tags) .where(any_tags: true) .or(Antenna.availables.left_joins(:antenna_accounts).left_joins(:antenna_domains).left_joins(:antenna_tags).where(antenna_tags: { exclude: false, tag: @status.tags }))
antennas = antennas.where(account: @status.account.followers) if @status.visibility.to_sym == :unlisted antennas = antennas.where(account: @status.account.followers) if @status.visibility.to_sym == :unlisted
antennas = antennas.where(with_media_only: false) if !@status.with_media? antennas = antennas.where(with_media_only: false) if !@status.with_media?
antennas = antennas.where.not(account: @status.account.blocking)
antennas = antennas.includes(:antenna_accounts).includes(:antenna_domains).includes(:antenna_tags)
antennas.in_batches do |ans| antennas.in_batches do |ans|
ans.each do |antenna| ans.each do |antenna|
next if !antenna.enabled? next if !antenna.enabled?
next if @status.account.blocking?(antenna.account)
next if antenna.keywords.any? && !([nil, :public].include?(@status.searchability&.to_sym)) next if antenna.keywords.any? && !([nil, :public].include?(@status.searchability&.to_sym))
next if antenna.keywords.any? && !antenna.keywords.any? { |keyword| @status.text.include?(keyword) } next if antenna.keywords.any? && !antenna.keywords.any? { |keyword| @status.text.include?(keyword) }
next if antenna.exclude_keywords.any? && antenna.exclude_keywords.any? { |keyword| @status.text.include?(keyword) } next if antenna.exclude_keywords&.any? { |keyword| @status.text.include?(keyword) }
next if antenna.antenna_accounts.where(exclude: true, account: @status.account).any? next if antenna.exclude_accounts&.include?(@status.account_id)
next if antenna.antenna_domains.where(exclude: true, name: @status.account.domain).any? next if antenna.exclude_domains&.include?(domain)
next if antenna.antenna_tags.where(exclude: true, tag: @status.tags).any? next if antenna.exclude_tags&.any? { |tag_id| tag_ids.include?(tag_id) }
lists << antenna.list lists << antenna.list_id
end end
end end
lists = lists.uniq lists = lists.uniq
if lists.any? if lists.any?
FeedInsertWorker.push_bulk(lists) do |list| FeedInsertWorker.push_bulk(lists) do |list|
[@status.id, list.id, 'list', { 'update' => update? }] [@status.id, list, 'list', { 'update' => update? }]
end end
end end
end end

View file

@ -0,0 +1,7 @@
class AddExcludesToAntennas < ActiveRecord::Migration[6.1]
def change
add_column :antennas, :exclude_domains, :jsonb
add_column :antennas, :exclude_accounts, :jsonb
add_column :antennas, :exclude_tags, :jsonb
end
end

View file

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2023_04_23_233429) do ActiveRecord::Schema.define(version: 2023_04_26_013738) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -117,6 +117,8 @@ ActiveRecord::Schema.define(version: 2023_04_23_233429) do
t.integer "min_reblogs" t.integer "min_reblogs"
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.integer "min_emojis"
t.boolean "keep_self_emoji", default: true, null: false
t.index ["account_id"], name: "index_account_statuses_cleanup_policies_on_account_id" t.index ["account_id"], name: "index_account_statuses_cleanup_policies_on_account_id"
end end
@ -300,6 +302,9 @@ ActiveRecord::Schema.define(version: 2023_04_23_233429) do
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.datetime "expires_at" t.datetime "expires_at"
t.boolean "with_media_only", default: false, null: false t.boolean "with_media_only", default: false, null: false
t.jsonb "exclude_domains"
t.jsonb "exclude_accounts"
t.jsonb "exclude_tags"
t.index ["account_id"], name: "index_antennas_on_account_id" t.index ["account_id"], name: "index_antennas_on_account_id"
t.index ["any_accounts"], name: "index_antennas_on_any_accounts" t.index ["any_accounts"], name: "index_antennas_on_any_accounts"
t.index ["any_domains"], name: "index_antennas_on_any_domains" t.index ["any_domains"], name: "index_antennas_on_any_domains"