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

48 lines
1.3 KiB

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