Neography is a thin Ruby wrapper to the Neo4j Rest API, for more information:
If you want to the full power of Neo4j, you will want to use JRuby and the excellent Neo4j.rb gem at github.com/andreasronge/neo4j
gem install 'neography'
After that, in your ruby script:
require 'rubygems' require 'neography'
in order to access the functionality.
I am hosting an instance of Neo4j (1.2 M5) at neography.org for you to try out.
You can see the administration at: Neo4j Web Admin
# Add this to your ruby file to use it Neography::Config.server = 'neography.org'
for use: json httparty for development: rspec net-http-spy fakeweb
Just add gem ‘neography’ to your Gemfile and run bundle install
A thin ruby wrapper Neography::Rest which tries to mirror the Neo4j Rest API and returns JSON or Nil:
# protocol, server, port, log_file, log_enabled, max_threads
@neo = Neography::Rest.new ('http://', '192.168.10.1', 7479, 'log/neography.log', true, 50)
Default Parameters are:
@neo = Neography::Rest.new ('http://', 'localhost', 7474, '/neography.log', false, 20)
To Use:
@neo = Neography::Rest.new @neo.get_root # Get the root node node1 = @neo.create_node # Create an empty node node2 = @neo.create_node("age" => 31, "name" => "Max") # Create a node with some properties @neo.get_node(node2) # Get a node and its properties @neo.delete_node(node2) # Delete an unrelated node @neo.delete_node!(node2) # Delete a node and all its relationships @neo.reset_node_properties(node1, {"age" => 31}) # Reset a node's properties @neo.set_node_properties(node1, {"weight" => 200}) # Set a node's properties @neo.get_node_properties(node1) # Get just the node properties @neo.get_node_properties(node1, ["weight","age"]) # Get some of the node properties @neo.remove_node_properties(node1) # Remove all properties of a node @neo.remove_node_properties(node1, "weight") # Remove one property of a node @neo.remove_node_properties(node1, ["weight","age"]) # Remove multiple properties of a node rel1 = @neo.create_relationship("friends", node1, node2) # Create a relationship between node1 and node2 rel2 = @neo.get_relationship(rel1) # Get a relationship @neo.get_node_relationships(node1) # Get all relationships @neo.get_node_relationships(node1, "in") # Get only incoming relationships @neo.get_node_relationships(node1, "all", "enemies") # Get all relationships of type enemies @neo.get_node_relationships(node1, "in", "enemies") # Get only incoming relationships of type enemies @neo.delete_relationship(rel1) # Delete a relationship @neo.reset_relationship_properties(rel1, {"age" => 31}) # Reset a relationship's properties @neo.set_relationship_properties(rel1, {"weight" => 200}) # Set a relationship's properties @neo.get_relationship_properties(rel1) # Get just the relationship properties @neo.get_relationship_properties(rel1, ["since","met"]) # Get some of the relationship properties @neo.remove_relationship_properties(rel1) # Remove all properties of a relationship @neo.remove_relationship_properties(rel1, "since") # Remove one property of a relationship @neo.remove_relationship_properties(rel1, ["since","met"]) # Remove multiple properties of a relationship @neo.list_indexes # gives names and query templates for all defined indices @neo.add_to_index(index, key, value, node1) # adds a node to the specified index with the given key/value pair @neo.remove_from_index(index, key, value, node1) # removes a node from the specified index with the given key/value pair @neo.get_index(index, key, value) # queries the specified index with the given key/value pair @neo.get_path(node1, node2, relationships, depth=4, algorithm="shortestPath") # finds the shortest path between two nodes @neo.get_paths(node1, node2, relationships, depth=3, algorithm="allPaths") # finds all paths between two nodes nodes = @neo.traverse(node1, # the node where the traversal starts "nodes", # return_type "nodes", "relationships" or "paths" {"order" => "breadth first", # "breadth first" or "depth first" traversal order "uniqueness" => "node global", # See Uniqueness in API documentation for options. "relationships" => [{"type"=> "roommates", # A hash containg a description of the traversal "direction" => "all"}, # two relationships. {"type"=> "friends", # "direction" => "out"}], # "prune evaluator" => {"language" => "javascript", # A prune evaluator (when to stop traversing) "body" => "position.endNode().getProperty('age') < 21;"}, "return filter" => {"language" => "builtin", # "all" or "all but start node" "name" => "all"}, "depth" => 4}) # "depth" is a short-hand way of specifying a prune evaluator which prunes after a certain depth. # If not specified a depth of 1 is used and if a "prune evaluator" is specified instead of a depth, no depth limit is set.
Please see the specs for more examples.
Experimental:
nodes = @neo.create_nodes(5) # Create 5 empty nodes
nodes = @neo.create_nodes_threaded(5) # Create 5 empty nodes using threads
nodes = @neo.create_node_nodes([{"age" => 31, "name" => "Max"},
{"age" => 24, "name" => "Alex"}) # Create two nodes with properties
nodes = @neo.create_node_nodes_threaded([{"age" => 31, "name" => "Max"},
{"age" => 24, "name" => "Alex"}) # Create two nodes with properties threaded
nodes = @neo.get_nodes([17,86,397,33]) # Get four nodes by their id
one_set_nodes = @neo.create_nodes(3)
another_node = @neo.create_node("age" => 31, "name" => "Max")
nodes = @neo.get_nodes([one_set_nodes, another_node]) # Get four nodes
Trying to mimic the Neo4j.rb API.
Now we are returning full objects. The properties of the node or relationship can be accessed directly (node.name). The Neo4j ID is available by using node.neo_id .
@neo2 = Neography::Rest.new ('http://', '192.168.10.1')
Neography::Node.create # Create an empty node
Neography::Node.create("age" => 31, "name" => "Max") # Create a node with some properties
Neography::Node.create(@neo2, {"age" => 31, "name" => "Max"}) # Create a node on the server defined in @neo2
Neography::Node.create({"age" => 31, "name" => "Max"}, @neo2) # Same as above, but different order
Neography::Node.load(5) # Get a node and its properties by id
Neography::Node.load(existing_node) # Get a node and its properties by Node
Neography::Node.load("http://localhost:7474/db/data/node/2") # Get a node and its properties by String
Neography::Node.load(@neo2, 5) # Get a node on the server defined in @neo2
Neography::Node.load(5, @neo2) # Same as above, but different order
n1 = Node.create
n1.del # Deletes the node
n1.exist? # returns true/false if node exists in Neo4j
n1 = Node.create("age" => 31, "name" => "Max")
n1[:age] #returns 31 # Get a node property using [:key]
n1.name #returns "Max" # Get a node property as a method
n1[:age] = 24 # Set a node property using [:key] =
n1.name = "Alex" # Set a node property as a method
n1[:hair] = "black" # Add a node property using [:key] =
n1.weight = 190 # Add a node property as a method
n1[:name] = nil # Delete a node property using [:key] = nil
n1.name = nil # Delete a node property by setting it to nil
n2 = Neography::Node.create
new_rel = Neography::Relationship.create(:family, n1, n2) # Create a relationship from my_node to node2
new_rel.start_node # Get the start/from node of a relationship
new_rel.end_node # Get the end/to node of a relationship
new_rel.other_node(n2) # Get the other node of a relationship
existing_rel = Neography::Relationship.load(12) # Get an existing relationship by id
existing_rel.del # Delete a relationship
Neography::Relationship.create(:friends, n1, n2)
n1.outgoing(:friends) << n2 # Create outgoing relationship
n1.incoming(:friends) << n2 # Create incoming relationship
n1.both(:friends) << n2 # Create both relationships
n1.outgoing # Get nodes related by outgoing relationships
n1.incoming # Get nodes related by incoming relationships
n1.both # Get nodes related by any relationships
n1.outgoing(:friends) # Get nodes related by outgoing friends relationship
n1.incoming(:friends) # Get nodes related by incoming friends relationship
n1.both(:friends) # Get nodes related by friends relationship
n1.outgoing(:friends).incoming(:enemies) # Get nodes related by one of multiple relationships
n1.outgoing(:friends).depth(2) # Get nodes related by friends and friends of friends
n1.outgoing(:friends).depth(:all) # Get nodes related by friends until the end of the graph
n1.outgoing(:friends).depth(2).include_start_node # Get n1 and nodes related by friends and friends of friends
n1.outgoing(:friends).prune("position.endNode().getProperty('name') == 'Tom';")
n1.outgoing(:friends).filter("position.length() == 2;")
n1.rel?(:friends) # Has a friends relationship
n1.rel?(:outgoing, :friends) # Has outgoing friends relationship
n1.rel?(:friends, :outgoing) # same, just the other way
n1.rel?(:outgoing) # Has any outgoing relationships
n1.rel?(:both) # Has any relationships
n1.rel?(:all) # same as above
n1.rel? # same as above
n1.rels # Get node relationships
n1.rels(:friends) # Get friends relationships
n1.rels(:friends).outgoing # Get outgoing friends relationships
n1.rels(:friends).incoming # Get incoming friends relationships
n1.rels(:friends,:work) # Get friends and work relationships
n1.rels(:friends,:work).outgoing # Get outgoing friends and work relationships
n1.all_paths_to(n2).incoming(:friends).depth(4) # Gets all paths of a specified type
n1.all_simple_paths_to(n2).incoming(:friends).depth(4) # for the relationships defined
n1.all_shortest_paths_to(n2).incoming(:friends).depth(4) # at a maximum depth
n1.path_to(n2).incoming(:friends).depth(4) # Same as above, but just one path.
n1.simple_path_to(n2).incoming(:friends).depth(4)
n1.shortest_path_to(n2).incoming(:friends).depth(4)
n1.shortest_path_to(n2).incoming(:friends).depth(4).rels # Gets just relationships in path
n1.shortest_path_to(n2).incoming(:friends).depth(4).nodes # Gets just nodes in path
See Neo4j API for:
A couple of examples borrowed from Matthew Deiters’s Neo4jr-social
-
More Tests
-
More Examples
-
Mixins ?
-
Neography - MIT, see the LICENSE file github.com/maxdemarzi/neography/tree/master/LICENSE.
-
Lucene - Apache, see lucene.apache.org/java/docs/features.html
-
Neo4j - Dual free software/commercial license, see neo4j.org