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.

52 lines
1.4 KiB

  1. class FollowSuggestion
  2. class << self
  3. def get(for_account_id, limit = 10)
  4. neo = Neography::Rest.new
  5. query = <<END
  6. START a=node:account_index(Account={id})
  7. MATCH (a)-[: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. START a=node:account_index(Account={id})
  33. MATCH (b)
  34. WHERE a <> b
  35. AND NOT (a)-[:follows]->(b)
  36. RETURN b.account_id
  37. ORDER BY b.nodeRank DESC
  38. LIMIT {limit}
  39. END
  40. neo.execute_query(query, id: for_account_id, limit: limit)
  41. end
  42. end
  43. end