グラフ DB で

フレンド機能実装

User.has_and_belongs_to_many :friendships

(

  SELECT u.*
  FROM friendships f JOIN users u
  ON f.friend_id = u.id
  WHERE f.user_id = 123

) UNION (

  SELECT u.*
  FROM friendships f JOIN users u
  ON f.user_id = u.id
  WHERE f.friend_id = 123

)
class User < ActiveRecord::Base
  has_many :friendships
  has_many :inverse_friendships, class_name: "Friendship",
                                 foreign_key: :friend_id

  def friends
    friend_ids = friendships.pluck(:friend_id) +
                 inverse_friendships.pluck(:user_id)

    User.where(id: friend_ids)
  end
end

The (Non-Perfect) Mathematics of Trust

カリーニングラードのオイラー路

AirBnB 信頼制度

SNS のソーシャルグラフ

Google の PageRank アルゴリズム

Neo4j

Cypher

MATCH (you {name:"You"})
MATCH (expert)-[:WORKED_WITH]->(db:Database {name:"Neo4j"})
MATCH path = shortestPath( (you)-[:FRIEND*..5]-(expert) )
RETURN db, expert, path

 
 
 
 

neo4j gem

デモ

https://github.com/rastamhadi/tomodachi

has_many :friendships
has_many :inverse_friendships, class_name: "Friendship",
                               foreign_key: :friend_id


# has_many :friendships
# has_many :inverse_friendships, class_name: "Friendship",
#                                foreign_key: :friend_id

has_many :both, :friends, type: :friend, model_class: 'User'
def friends
  friend_ids = friendships.pluck(:friend_id) +
               inverse_friendships.pluck(:user_id)

  User.where(id: friend_ids)
end


# def friends
#   friend_ids = friendships.pluck(:friend_id) +
#                inverse_friendships.pluck(:user_id)
# 
#   User.where(id: friend_ids)
# end

@user.friends

結論

JOIN 辛 :tangerine:

:arrow_down:

グラフ DB

グラフ DB で

フレンド機能実装