Revert friends-of-friends follow recommendation query to using a CTE (#29619)
This commit is contained in:
		
							parent
							
								
									b5115850bb
								
							
						
					
					
						commit
						d5063072c3
					
				| @ -7,14 +7,35 @@ class AccountSuggestions::FriendsOfFriendsSource < AccountSuggestions::Source | ||||
|   end | ||||
| 
 | ||||
|   def source_query(account, limit: DEFAULT_LIMIT) | ||||
|     first_degree = account.following.where.not(hide_collections: true).select(:id).reorder(nil) | ||||
|     base_account_scope(account) | ||||
|       .joins(:account_stat) | ||||
|       .joins(:passive_relationships).where(passive_relationships: { account_id: first_degree }) | ||||
|       .group('accounts.id, account_stats.id') | ||||
|       .reorder(frequency: :desc, followers_count: :desc) | ||||
|       .limit(limit) | ||||
|       .pluck(Arel.sql('accounts.id, COUNT(*) AS frequency, followers_count')) | ||||
|     Account.find_by_sql([<<~SQL.squish, { id: account.id, limit: limit }]).map { |row| [row.id, row.frequency, row.followers_count] } | ||||
|       WITH first_degree AS ( | ||||
|           SELECT target_account_id | ||||
|           FROM follows | ||||
|           JOIN accounts AS target_accounts ON follows.target_account_id = target_accounts.id | ||||
|           WHERE account_id = :id | ||||
|             AND NOT target_accounts.hide_collections | ||||
|       ) | ||||
|       SELECT accounts.id, COUNT(*) AS frequency, account_stats.followers_count as followers_count | ||||
|       FROM accounts | ||||
|       JOIN follows ON follows.target_account_id = accounts.id | ||||
|       JOIN account_stats ON account_stats.account_id = accounts.id | ||||
|       LEFT OUTER JOIN follow_recommendation_mutes ON follow_recommendation_mutes.target_account_id = accounts.id AND follow_recommendation_mutes.account_id = :id | ||||
|       WHERE follows.account_id IN (SELECT * FROM first_degree) | ||||
|         AND NOT EXISTS (SELECT 1 FROM blocks b WHERE b.target_account_id = follows.target_account_id AND b.account_id = :id) | ||||
|         AND NOT EXISTS (SELECT 1 FROM blocks b WHERE b.target_account_id = :id AND b.account_id = follows.target_account_id) | ||||
|         AND NOT EXISTS (SELECT 1 FROM mutes m WHERE m.target_account_id = follows.target_account_id AND m.account_id = :id) | ||||
|         AND (accounts.domain IS NULL OR NOT EXISTS (SELECT 1 FROM account_domain_blocks b WHERE b.account_id = :id AND b.domain = accounts.domain)) | ||||
|         AND NOT EXISTS (SELECT 1 FROM follows f WHERE f.target_account_id = follows.target_account_id AND f.account_id = :id) | ||||
|         AND follows.target_account_id <> :id | ||||
|         AND accounts.discoverable | ||||
|         AND accounts.suspended_at IS NULL | ||||
|         AND accounts.silenced_at IS NULL | ||||
|         AND accounts.moved_to_account_id IS NULL | ||||
|         AND follow_recommendation_mutes.target_account_id IS NULL | ||||
|       GROUP BY accounts.id, account_stats.id | ||||
|       ORDER BY frequency DESC, account_stats.followers_count ASC | ||||
|       LIMIT :limit | ||||
|     SQL | ||||
|   end | ||||
| 
 | ||||
|   private | ||||
|  | ||||
| @ -76,19 +76,19 @@ RSpec.describe AccountSuggestions::FriendsOfFriendsSource do | ||||
|       it 'contains correct underlying source data' do | ||||
|         expect(source_query_values) | ||||
|           .to contain_exactly( | ||||
|             [eugen.id, 2, 3], # Followed by 2 friends of bob (eve, mallory), 3 followers total (breaks tie) | ||||
|             [john.id, 2, 2],  # Followed by 2 friends of bob (eve, mallory), 2 followers total | ||||
|             [neil.id, 1, 2],  # Followed by 1 friends of bob (mallory), 2 followers total (breaks tie) | ||||
|             [jerk.id, 1, 1]   # Followed by 1 friends of bob (eve), 1 followers total | ||||
|             [john.id, 2, 2],  # Followed by 2 friends of bob (eve, mallory), 2 followers total (breaks tie) | ||||
|             [eugen.id, 2, 3], # Followed by 2 friends of bob (eve, mallory), 3 followers total | ||||
|             [jerk.id, 1, 1],  # Followed by 1 friends of bob (eve), 1 followers total (breaks tie) | ||||
|             [neil.id, 1, 2]   # Followed by 1 friends of bob (mallory), 2 followers total | ||||
|           ) | ||||
|       end | ||||
| 
 | ||||
|       def expected_results | ||||
|         [ | ||||
|           [eugen.id, :friends_of_friends], | ||||
|           [john.id, :friends_of_friends], | ||||
|           [neil.id, :friends_of_friends], | ||||
|           [eugen.id, :friends_of_friends], | ||||
|           [jerk.id, :friends_of_friends], | ||||
|           [neil.id, :friends_of_friends], | ||||
|         ] | ||||
|       end | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user