闭社主体 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.

47 lines
1.5 KiB

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