闭社主体 forked from https://github.com/tootsuite/mastodon
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

50 lines
1.4 KiB

  1. # frozen_string_literal: true
  2. class FollowSuggestion
  3. class << self
  4. def get(for_account_id, limit = 10)
  5. neo = Neography::Rest.new
  6. query = <<END
  7. MATCH (a {account_id: {id}})-[:follows]->(b)-[:follows]->(c)
  8. WHERE a <> c
  9. AND NOT (a)-[:follows]->(c)
  10. RETURN DISTINCT c.account_id, count(b), c.nodeRank
  11. ORDER BY count(b) DESC, c.nodeRank DESC
  12. LIMIT {limit}
  13. END
  14. results = neo.execute_query(query, id: for_account_id, limit: limit)
  15. if results.empty? || results['data'].empty?
  16. results = fallback(for_account_id, limit)
  17. elsif results['data'].size < limit
  18. results['data'] = (results['data'] + fallback(for_account_id, limit - results['data'].size)['data']).uniq
  19. end
  20. account_ids = results['data'].map(&:first)
  21. blocked_ids = Block.where(account_id: for_account_id).pluck(:target_account_id)
  22. accounts_map = Account.where(id: account_ids - blocked_ids).with_counters.map { |a| [a.id, a] }.to_h
  23. account_ids.map { |id| accounts_map[id] }.compact
  24. rescue Neography::NeographyError, Excon::Error::Socket => e
  25. Rails.logger.error e
  26. return []
  27. end
  28. private
  29. def fallback(for_account_id, limit)
  30. neo = Neography::Rest.new
  31. query = <<END
  32. MATCH (b)
  33. RETURN b.account_id
  34. ORDER BY b.nodeRank DESC
  35. LIMIT {limit}
  36. END
  37. neo.execute_query(query, id: for_account_id, limit: limit)
  38. end
  39. end
  40. end