-
-
Save andreasronge/394786 to your computer and use it in GitHub Desktop.
require 'rubygems' | |
require 'neo4j' | |
include Neo4j | |
Transaction.new | |
# create some people | |
andreas = Node.new :name => 'andreas' | |
peter = Node.new :name => 'peter' | |
kalle = Node.new :name => 'kalle' | |
sune = Node.new :name => 'sune' | |
adam = Node.new :name => 'adam' | |
# create some composers/artists | |
madonna = Node.new :name => 'madonna' | |
beethoven = Node.new :name => 'beethoven' | |
schubert = Node.new :name => 'schubert' | |
brahms = Node.new :name => 'brahms' | |
pink_floyed = Node.new :name => 'pink floyed' | |
grieg = Node.new :name => 'grieg' | |
mozart = Node.new :name => 'mozart' | |
# make relationships, who like what music | |
adam.rels.outgoing(:likes) << beethoven << brahms << grieg << mozart << pink_floyed | |
andreas.rels.outgoing(:likes) << beethoven << brahms << mozart | |
peter.rels.outgoing(:likes) << beethoven << brahms << schubert | |
kalle.rels.outgoing(:likes) << brahms << pink_floyed | |
sune.rels.outgoing(:likes) << pink_floyed << madonna | |
# utility method, returns an array of composer nodes | |
def composers_for(person) | |
[*person.outgoing(:likes)] | |
end | |
# prints out recommendations for the given person | |
def recommend(person) | |
# which composers does this person like ? | |
my_composers = composers_for(person) | |
# find all other people liking those composers | |
other_people = person.outgoing(:likes).incoming(:likes).depth(2).filter{|f| f.depth == 2} | |
# for each of those people, sort by the number of matching composers | |
# so that the most relevant recommendations are printed first | |
other_people.sort_by{|p| (composers_for(p) & my_composers).size}.reverse.each do |other_person| | |
# then print out those composers that he don't have | |
puts "Recommendation from #{other_person[:name]}" | |
(composers_for(other_person) - my_composers).each do |s| | |
puts " composer #{s[:name]}" | |
end | |
end | |
end | |
recommend(andreas) | |
Transaction.finish |
Yes, Neo4j does not slow down for larger data set. The traversal speed will remain the same even if the data size increases.
Also, I think it is easier to program a graphy problem in a graph db.
Hi Andreas,
thanks for your reply. I'm really curious how it feels like to work with Neo4j and am looking forward to trying it out!
Phillip
Yes, it requires a new way of thinking. Like many NoSQL databases Neo4j is very simple, but it requires that you have to do some more thinking - which is great fun.
For example you can implement your own indexing in Neo4j with a tree of nodes connected to your data nodes (e.g. for a spatial index). It's important to make sure that the node space is spread out -
e.g that one node does not have several thousands of relationships to other nodes.
Would be create to get some feedback, missing features/documenation/performance ...
Thank you for this example, but I don't see how Neo4j helps here. It seems to me this is just as easy to implement with SQL (see below). Does Neo4j handle larger data sets better than SQL, or why would I use it in this case?
Table LIKES
user_id composer_id
1 1
1 3
2 1
2 2
2 4
2 5
find user 1's preferences
user1_composers = select composer_id from likes where user_id=1
find users which like the same composer
users_with_same_like = select user_id from likes where composer_id IN(user1_composers)
find composers the other users like
recommendations = select count(composer_id) as _cnt, composer_id where user_id IN(users_with_same_like) and composer_id NOT IN(user1_composers) ORDER BY _cnt DESC