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. 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. if results.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 self.fallback(for_account_id, limit)
  29. neo = Neography::Rest.new
  30. query = <<END
  31. START a=node:account_index(Account={id})
  32. MATCH (b)
  33. WHERE a <> b
  34. AND NOT (a)-[:follows]->(b)
  35. RETURN b.account_id
  36. ORDER BY b.nodeRank DESC
  37. LIMIT {limit}
  38. END
  39. neo.execute_query(query, id: for_account_id, limit: limit)
  40. end
  41. end