Skip to content
Snippets Groups Projects
Commit 7075cef8 authored by Eugen Rochko's avatar Eugen Rochko
Browse files

Adding sort by node rank to follow suggestions and fallback to most influential users

parent 492a682e
No related branches found
No related tags found
No related merge requests found
......@@ -8,6 +8,7 @@ env:
- RAILS_ENV=test
- NEO4J_HOST=localhost
- NEO4J_PORT=7575
- TRAVIS_NODE_VERSION="4"
addons:
postgresql: 9.4
......@@ -21,6 +22,7 @@ services:
bundler_args: --without development production --retry=3 --jobs=3
install:
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION
- npm install -g npm@3
- npm install -g yarn
- bundle install
......@@ -29,4 +31,6 @@ install:
before_script:
- bundle exec rails db:create db:migrate
script: bundle exec rspec
script:
- bundle exec rspec
- npm test
......@@ -57,6 +57,8 @@ Consult the example configuration file, `.env.production.sample` for the full li
- PostgreSQL
- Redis
- Neo4J (optional)
- GraphAware NodeRank
## Running with Docker and Docker-Compose
......@@ -86,6 +88,7 @@ The container has two volumes, for the assets and for user uploads. The default
- `rake mastodon:push:clear` unsubscribes from PuSH notifications for remote users that have no local followers. You may not want to actually do that, to keep a fuller footprint of the fediverse or in case your users will soon re-follow
- `rake mastodon:push:refresh` re-subscribes PuSH for expiring remote users, this should be run periodically from a cronjob and quite often as the expiration time depends on the particular hub of the remote user
- `rake mastodon:feeds:clear` removes all timelines, which forces them to be re-built on the fly next time a user tries to fetch their home/mentions timeline. Only for troubleshooting
- `rake mastodon:graphs:sync` re-imports all follow relationships into Neo4J. Only for troubleshooting
Running any of these tasks via docker-compose would look like this:
......
class FollowSuggestion
def self.get(for_account_id, limit = 6)
neo = Neography::Rest.new
account_ids = neo.execute_query('START a=node:account_index(Account={id}) MATCH (a)-[:follows]->(b)-[:follows]->(c) WHERE a <> c AND NOT (a)-[:follows]->(c) RETURN DISTINCT c.account_id', id: for_account_id)
Account.where(id: account_ids['data'].map(&:first) - Block.where(account_id: for_account_id).pluck(:target_account_id)).limit(limit) unless account_ids.empty?
query = <<END
START a=node:account_index(Account={id})
MATCH (a)-[:follows]->(b)-[:follows]->(c)
WHERE a <> c
AND NOT (a)-[:follows]->(c)
RETURN DISTINCT c.account_id
ORDER BY c.nodeRank
LIMIT {limit}
END
results = neo.execute_query(query, id: for_account_id, limit: limit)
return fallback(for_account_id, limit) if results.empty?
map_to_accounts(for_account_id, results)
rescue Neography::NeographyError, Excon::Error::Socket => e
Rails.logger.error e
[]
return []
end
private
def self.fallback(for_account_id, limit)
neo = Neography::Rest.new
query = 'MATCH (a) WHERE a.account_id <> {id} RETURN a.account_id ORDER BY a.nodeRank DESC LIMIT {limit}'
results = neo.execute_query(query, id: for_account_id, limit: limit)
map_to_accounts(for_account_id, results)
rescue Neography::NeographyError, Excon::Error::Socket => e
Rails.logger.error e
return []
end
def self.map_to_accounts(for_account_id, results)
return [] if results.empty?
account_ids = results['data'].map(&:first)
blocked_ids = Block.where(account_id: for_account_id).pluck(:target_account_id)
accounts_map = Account.where(id: account_ids - blocked_ids).map { |a| [a.id, a] }.to_h
account_ids.map { |id| accounts_map[id] }.compact
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment