Nodes, Properties, and Relationships

The Neo4j node space consists of three basic elements: nodes, relationships that connect nodes, and properties, which are attached to both nodes and relationships. All relationships have a type. For example, if the node space represents a social network, a relationship type could be knows, as in one friend knows another. Much of the meaning of a node space is encoded in the relationship types of the application.

1 Creating Nodes

Example of creating a Neo4j::Node

require "rubygems"
require 'neo4j'

Neo4j::Transaction.run do
  node = Neo4j::Node.new
end

Neo4j::Node.new returns a Java Neo4j org.neo4j.graphdb.Node object, which has been modified to “feel” more like ruby.

2 Transactions

All Neo4j write operation must be wrapped in a transaction as shown above. For example:

Neo4j::Transaction.run do
  # neo4j operations goes here
end

Neo4j::Rails::Model#transaction is a convenient wrapper for this.

The Neo4j::Transaction returns a Java org.neo4j.graph.Transaction. For more information, see Neo4j Transactions.

3 Properties

Example of setting properties:

Neo4j::Node.new :name=>'foo', :age=>123, :hungry => false, 4 => 3.14
# which is same as the following:
node = Neo4j::Node.new
node[:name] = 'foo'
node[:age]  = 123
node['hungry'] = false
node[4] = 3.14
node[:age] #  => 123

Properties can be of a primitive value (Fixnum, Float, TrueClass, FalseClass, String) and arrays of those primitive values. Also, @Date and DateTime can be saved if you declared them, see Type Conversion below.

Array Gotchas 1 all items in an array must be of the same type. Array Gotchas 2 You can’t change just one item in an array (they are mutable). You have to create a new array each time you add, remove, change one item.

3.1 Type Conversion

If you declare a type of a property it can be converted into a primitive. Example

class Person
  include Neo4j::NodeMixin
  property :born, :type => DateTime
end

The :born property will be marshalled into a Java long value automatically since there is a default registered type conversion for DateTime. This default can be found in the Neo4j::Config object under the key conversions.

You can add your own conversion if you want to save a Ruby object with a property.

4 Creating Relationships

Example of creating an outgoing Neo4j::Relationship from node1 to node2 of type friends

node1 = Neo4j::Node.new
node2 = Neo4j::Node.new
Neo4j::Relationship.new(:friends, node1, node2)
# which is same as
node1.outgoing(:friends) << node2

5 Accessing Relationships

Example of getting relationships:

node1.rels # => an Enumerable of all incoming and outgoing relationship of any type
node1.rel?  # => true if there are any relationship of any type
node1.rels(:friends) # => all relationship of type friends, both incoming and outgoing
node1.rels(:friends).outgoing # => all outgoing relationship of type friends
node1.rel(:both, :best_friend)  # => returns one relationship, nil or throws an exception if there are more the two relationship from this node
node1.rel(:incoming, :best_friend)

Note that _rels takes different arguments from rels!

node1.rels(:both, :friends)

6 Finding Relationships between two nodes

You can find all relationships between two nodes like this:

node_a.rels.to_other(node_b)  # => an enumerable of all relationship between those two nodes
node_a.rels(:friends).outgoing.to_other(node_b)  # => an enumerable of relationship of only outgoing relationships of type friend

7 Deleting Relationships between two nodes

You can combine the to_other method with del to delete relationships between two nodes (see above):

node_a.rels.to_other(node_b).del  # => an enumerable of all relationship between those two nodes
node_a.rels(:friends).outgoing.to_other(node_b).del  # => an enumerable of relationship of only outgoing relationships of type friend

8 Properties on Relationships

Example of setting properties on relationships:

rel = node1.rels(:friends).outgoing.first  # get the first relationship object 
rel[:since] = 1982