Nodes and Relationships

Josh Adell edited this page Oct 7, 2013 · 13 revisions

Working with Nodes

Nodes are the first of the two major entity types in a graph database. A node is a collection of zero or more key-value pairs. neo4jphp makes it very easy to create and work with nodes.

Create a Node

The following code snippet creates some nodes, sets some properties on each, and saves the nodes to the server. The $client variable was created according to Introduction - Creating a Connection to Neo4j.

$arthur = $client->makeNode();
$arthur->setProperty('name', 'Arthur Dent')
    ->setProperty('mood', 'nervous')
    ->setProperty('home', 'small cottage')
    ->save();

$ford = $client->makeNode();
$ford->setProperty('name', 'Ford Prefect')
    ->setProperty('occupation', 'travel writer')
    ->save();

$arthurId = $arthur->getId();

Each Node::setProperty() call returns the Node object, allowing the calls to be chained together fluently.

Node::save() will return the Node object if it was saved successfully to the server, or throw an exception otherwise. The exception will contain the full server response.

Retrieve a Node by ID and Update

Now that the node has been created, the node's id can be used to retrieve the node from the server later. The following code retrieves the node and prints its properties:

$character = $client->getNode($arthurId);

foreach ($character->getProperties() as $key => $value) {
    echo "$key: $value\n";
}
// prints:
//   name: Arthur Dent
//   mood: nervous
//   home: small cottage

$character->removeProperty('mood')
    ->setProperty('home', 'demolished')
    ->save();

foreach ($character->getProperties() as $key => $value) {
    echo "$key: $value\n";
}
// prints:
//   name: Arthur Dent
//   home: demolished

The call to Client::getNode() will return a Node object if the Node was found successfully or null if not.

Node::getProperties() returns an array of all properties on a node, keyed by the property name. Individual properties can be retrieved with Node::getProperty and removed completely with Node::removeProperty(). Any changes to the node will not be persisted to the server until Node::save() is called again.

Delete a Node

A node can be deleted as long as its ID has been set. Also note that a node cannot be deleted if it is the start or end point of any relationship.

$earth = $client->getNode(123);
$earth->delete();

Node::delete() will return the Node object if it was deleted successfully from the server, or throw an exception otherwise.

Working with Relationships

Relationships in a graph database join two nodes together. Relationships are uni-directional, that is, one node is designated as the start node and the other is the end node. Choosing which node is the start or the end depends on your application's domain. Relationships can be traversed in any direction, so the decision is purely a semantic one.

Unlike relational database foreign keys, relationships can have properties attached to them, just like nodes. Most of the methods for working with node properties also apply to relationships. Relationships must have a "type" that identifies the way in which the two nodes are related.

Create a Relationship

There are two methods for creating a Relationship object in neo4jphp. The easiest way is to use the start node and pass it the end node. You can also instantiate a Relationship object directly, but then you are responsible for setting the start and end nodes and the type. The following code snippet demonstrates both methods:

$arthur = $client->makeNode()->save();
$earth = $client->makeNode()->save();
$vogons = $client->makeNode()->save();

// Method 1
$arthur->relateTo($earth, 'LIVES_ON')
    ->setProperty('duration', 'all his life')
    ->save();

// Method 2
$demolition = $client->makeRelationship();
$demolition->setStartNode($vogons)
    ->setEndNode($earth)
    ->setType('DEMOLISHED')
    ->setProperty('method', 'Vogon Constructor Fleet')
    ->save();

The first thing to note is that both the start and end nodes of a relationship must be saved (or at least have their IDs set) before the relationship can be saved.

The second thing to note is that with method 2, you are responsible for setting the endpoint nodes and the type. The relationship cannot be saved unless all three are set.

Node::relateTo() returns a Relationship object.

Relationship::save() will return the Relationship object if it was saved successfully to the server, or throw an exception otherwise. A successfully saved relationship will have an ID that can be retrieved using Relationship::getId()

Retrieve a Relationship by ID and Update

A relationship can be retrieved the same way as a node: by calling Client::getRelationship() with the relationship ID. Calling Relationship::save() again will update any properties that have been changed.

The call to Client::getRelationship() will return a Relationship if the Relationship was found successfully or null if not.

Retrieve Relationships from a Node

Just like relationships can be created from a node, they can also be retrieved from a node. When retrieving relationships, you can filter the list of relationships by type and direction, or either, or neither.

// $arthur, $ford and $earth are nodes created earlier

$rel1 = $arthur->relateTo($earth, 'LIVES_ON')->save();
$rel2 = $arthur->relateTo($ford, 'KNOWS')->save();
$rel3 = $ford->relateTo($arthur, 'KNOWS')->save();

// returns $rel1, $rel2, $rel3
$arthurRelationships = $arthur->getRelationships();

// returns $rel1, $rel2
$arthurOutgoingRelationships = $arthur->getRelationships(array(), Relationship::DirectionOut);

// returns $rel2
$arthurOutgoingKnowsRelationships = $arthur->getRelationships(array('KNOWS'), Relationship::DirectionOut);

// returns $rel2, $rel3
$arthurKnowsRelationships = $arthur->getRelationships(array('KNOWS'));

Node::getRelationships() takes an array of types to filter, and a direction. Valid directions are Relationship::DirectionAll (the default), Relationship::DirectionIn and Relationship::DirectionOut.

Delete a Relationship

A relationship can be deleted as long as its ID has been set.

$habitat = $client->getRelationship(123);
$habitat->delete();

Relationship::delete() will return the Relationship object if it was deleted successfully from the server, or throw an exception otherwise.