Okay, For those of you who don’t know what Neo4j is, it’s a graph database server. You should probably research graph databases or read up on Neo4j on http://neo4j.org/ . Neo4j is written on java and installs in a few quick command line steps on a Mac. If you are using pesky Linux or screwy Windows, you ought to follow the installation instructions as these boxes don’t come pre-installed with Java unlike osX.
Neo4j doesn’t support PHP straight away so therefore I tried using the php API recommended by them. This one is at https://github.com/onewheelgood/Neo4J-REST-PHP-API-client . The GuitHub repo says the last date it was updated was in 2010 and I couldn’t get the API to work. After a few annoying php errors, I gave up on the whole API idea. I decided to look through the documentation and figured that Neo4j supports REST calls elegantly through json objects and the curl examples seemed pretty self-explanatory.
I decided to write a small Neo4j json friendly Curl Request() function that communicates with the API and put it up in a test.php function. Got it to work the way I wanted with a few tweaks and everything seemed fine so far. If you’re satisfied with what you’ve read so far and you just want the function and the REST API reference, I’ll spare you the trouble of the rest of my post.
The REST API documentation is here at : http://components.neo4j.org/neo4j-server/snapshot/rest.html
And my simple function is here :
function string_begins_with($string, $search)
{
return (strncmp($string, $search, strlen($search)) == 0);
}
function request($service, $data, $return_type="array")
{
if (!string_begins_with ($service, 'http://'))
$url = 'http://localhost:7474/'.$service ;
else
$url = $service ;
$fields = $data ;
$fields_string = '' ;
//url-ify the data for the POST
if ($data != NULL)
$post_data = json_encode($data) ;
//open connection
$ch = curl_init();
//set the url
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
if ($data != NULL) {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$headers = array(
'Content-Length: ' . strlen($post_data),
'Content-Type: application/json',
'Accept: application/json'
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
} else {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
}
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true) ;
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
if ($result)
{
if ($return_type == "array")
return (json_decode($result, true)) ;
else
return (json_decode($result)) ;
}
}
In the example that I’m using below, I’ve created a social network between 10 famous people and I attempt to trace the path between two people from within that network. All this is done using the request method from above so therefore paste your code accordingly. We now create the models of the 10 people with their name and their ages.
// Create the nodes
$response = request('db/data/node', array ('name'=> 'Jennifer Connely', 'age' => '33')) ;
$jenniferConnelyNode = $response ;
$response = request('db/data/node', array ('name'=> 'Mark Walberg', 'age' => '30')) ;
$markWalbergNode = $response ;
$response = request('db/data/node', array ('name'=> 'Owen Wilson', 'age' => '38')) ;
$owenWilsonNode = $response ;
$response = request('db/data/node', array ('name'=> 'George Lucas', 'age' => '56')) ;
$georgeLucasNode = $response ;
$response = request('db/data/node', array ('name'=> 'kevin spacy', 'age' => '48')) ;
$kevinSpaceyNode = $response ;
$response = request('db/data/node', array ('name'=> 'Quentin tarantino', 'age' => '36')) ;
$QuentinTarantinoNode = $response ;
$response = request('db/data/node', array ('name'=> 'Ashlee Simpson', 'age' => '24')) ;
$ashleeSimpsonNode = $response ;
$response = request('db/data/node', array ('name'=> 'Guy Ritchie', 'age' => '45')) ;
$guyRitchieNode = $response ;
$response = request('db/data/node', array ('name'=> 'George Clooney', 'age' => '52')) ;
$georgeClooneyNode = $response ;
$response = request('db/data/node', array ('name'=> 'Lewis Hamilton', 'age' => '28')) ;
$lewisHamiltonNode = $response ;
We store the node addresses from the $response variable, If you wish you see what the REST Server responds, you could always var_dump ($response) and do your stuff. We use these node addresses to map relationships between these people. Therefore I make one way relationships such as “Jennifer Connelly” Knows “Mark Walberg” and so on.
// Create Relationship between nodes
request ($jenniferConnelyNode['self']."/relationships/", array ("to"=> $markWalbergNode['self'], "type"=>"knows")) ;
request ($jenniferConnelyNode['self']."/relationships/", array ("to"=> $owenWilsonNode['self'], "type"=>"knows")) ;
request ($markWalbergNode['self']."/relationships/", array ("to"=> $owenWilsonNode['self'], "type"=>"knows")) ;
request ($markWalbergNode['self']."/relationships/", array ("to"=> $kevinSpaceyNode['self'], "type"=>"knows")) ;
request ($owenWilsonNode['self']."/relationships/", array ("to"=> $markWalbergNode['self'], "type"=>"knows")) ;
request ($owenWilsonNode['self']."/relationships/", array ("to"=> $kevinSpaceyNode['self'], "type"=>"knows")) ;
request ($owenWilsonNode['self']."/relationships/", array ("to"=> $georgeLucasNode['self'], "type"=>"knows")) ;
request ($georgeLucasNode['self']."/relationships/", array ("to"=> $kevinSpaceyNode['self'], "type"=>"knows")) ;
request ($georgeLucasNode['self']."/relationships/", array ("to"=> $QuentinTarantinoNode['self'], "type"=>"knows")) ;
request ($georgeLucasNode['self']."/relationships/", array ("to"=> $guyRitchieNode['self'], "type"=>"knows")) ;
request ($kevinSpaceyNode['self']."/relationships/", array ("to"=> $ashleeSimpsonNode['self'], "type"=>"knows")) ;
request ($QuentinTarantinoNode['self']."/relationships/", array ("to"=> $guyRitchieNode['self'], "type"=>"knows")) ;
request ($QuentinTarantinoNode['self']."/relationships/", array ("to"=> $jenniferConnelyNode['self'], "type"=>"knows")) ;
request ($ashleeSimpsonNode['self']."/relationships/", array ("to"=> $georgeLucasNode['self'], "type"=>"knows")) ;
request ($ashleeSimpsonNode['self']."/relationships/", array ("to"=> $lewisHamiltonNode['self'], "type"=>"knows")) ;
request ($guyRitchieNode['self']."/relationships/", array ("to"=> $georgeClooneyNode['self'], "type"=>"knows")) ;
request ($georgeClooneyNode['self']."/relationships/", array ("to"=> $georgeLucasNode['self'], "type"=>"knows")) ;
request ($georgeClooneyNode['self']."/relationships/", array ("to"=> $ashleeSimpsonNode['self'], "type"=>"knows")) ;
request ($georgeClooneyNode['self']."/relationships/", array ("to"=> $lewisHamiltonNode['self'], "type"=>"knows")) ;
request ($lewisHamiltonNode['self']."/relationships/", array ("to"=> $kevinSpaceyNode['self'], "type"=>"knows")) ;
Once I have the relationships mapped, I can trace the path between any two people with another REST call. For more information on any of the parameters that I’m passing to the REST Server. Refer the Neo4j REST documentation from the link way up above. Neo4j can return the intermediate nodes between two nodes and therefore I can see how “Lewis Hamilton” knows “Mark Walberg”. If you’ve joined up all the pieces of code and put it together on a test.php with a successfully running Neo4j server, You should see the result on your browser.
// Find path between two nodes
$response = request ($lewisHamiltonNode['self']."/path", array ("to" => $markWalbergNode['self'],
"algorithm"=>"shortestPath",
"max_depth"=>6,
"relationships" =>array ('type'=> 'knows', 'direction'=>'out')
)) ;
if (isset ($response['nodes'])) {
$i = 0;
$len = count($response['nodes']);
foreach ($response['nodes'] as $node) {
$response = request ($node, NULL) ;
if (isset ($response['data'])) {
$data = $response['data'] ;
if ($i == 0)
echo "".$data['name']." knows " ;
else if ($i == $len - 1)
echo "".$data['name']."" ;
else
echo "".$data['name']." who knows " ;
$i++;
}
}
} else {
echo "Cant find a relationship" ;
}
I hope the above code helped
Rohit. Manohar