Created
May 8, 2010 21:27
-
-
Save andreasronge/394786 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, 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 ...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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