Discover Graph Databases with Neo4j and PHP

Christophe Willemsen
Christophe Willemsen
Share

In this post, we’ll be learning about Neo4j, the leading graph database, and ways to use it with PHP. In a followup post, we’ll be building a proper graph application powered by Silex.


Graph databases are now one of the core technologies of companies dealing with highly connected data.

Business graphs, social graphs, knowledge graphs, interest graphs and media graphs are frequently in the (technology) news – and for a reason. The graph model represents a very flexible way of handling relationships in your data, and graph databases provide fast and efficient storage, retrieval and querying for it.

Neo4j, the most popular graph database, has proven its ability to deal with massive amounts of highly connected data in many use-cases.

During the last GraphConnect conference, TomTom and Ebay’s Shuttle demonstrated the value a graph database adds to your company to, for instance, provide fantastic customer experiences or to enable complex route-map editing. Neo4j is developed and supported by Neo Technology – a startup which has grown into a well respected database company.

A short Introduction

For the newcomers, here is a short introduction to graph databases and Neo4j, apart from the theoretical glance we threw at it last year.

What is a Graph ?

A graph is a generic data structure, composed of of nodes (entities) connected by relationships. Sometimes, those are also called vertices and edges. In the property graph model, each node and relationship can be labeled and hold any number of properties describing it.

what-is-a-graph

image via Wikipedia

What is a Graph Database

A graph database is a database optimized for operations on connected data.
Graph databases provide high performance suitable for online operations by using dedicated storage structures for both nodes and relationships.
They don’t need to compute relationships (JOINS) at query time but store them efficiently as part of your data.

Let’s take a simple social application as an example, where users follow other users.

A user will be represented as a Node and can have a label and properties. Labels depict various roles for your nodes.

A Node

The link between these two users will be represented as a Relationship, which can also have properties and a Type to identify the nature of the relationship. Relationships add semantic meaning to your data.

Nodes with Relationship

Looking at the graph shows how natural it is to represent data in a graph and store it in a graph database.

MultipleNodesAndEdges

Cypher, the Neo4j Graph Query Language

Querying a graph may not appear to be straightforward. To make it easy, Neo4j developed Cypher, a declarative graph query language, focused on readability and expressiveness for humans as developers, administrators and domain experts.

Being declarative, Cypher focuses on expressing what to retrieve from a graph, rather than how to retrieve it.

The query language is comprised of several distinct clauses. You can read more details about them in the Neo4j manual.

Here are a few clauses used to read and update the graph:

  • MATCH: Finds the “example” graph pattern you provide in the graph and returns one path per found match.
  • WHERE: Filters results with predicates, much like in SQL. There are many more predicates in Cypher though, including collection operations and graph matches.
  • RETURN: Returns your query result in the form you need, as scalar values, graph elements or paths, or collections or even documents.
  • CREATE: Creates graph elements (nodes and relationships) with labels and properties.
  • MERGE: Matches existing patterns or create them. It’s a combination of MATCH and CREATE.

Cypher is all about patterns, it describes the visual representation you’ve already seen as textual patterns (using ASCII-art).
It uses round parentheses to depict nodes (like (m:Movie) or (me:Person:Developer)) and arrows (like --> or -[:LOVES]->) for relationships.

Looking at our last graph of users, a query that will retrieve Hannah Hilpert and the users following her will be written like the following :

MATCH (user:User {name:'Hannah Hilpert'})<-[:FOLLOWS]-(follower) 
RETURN user, follower

HannahFriendships


Neo4j and PHP

After this quick introduction to the Neo4j graph database (more here), let’s see how we can use it from PHP.

Neo4j is installed as a database server.
An HTTP-API is accessible for manipulating the database and issuing Cypher queries.

If you want to install and run the Neo4j graph database, you can download the latest version here : http://neo4j.com/download/, extract the archive on your computer and run the ./bin/neo4j start command. Note that this is only for *nix based systems.

Neo4j comes with a cool visual interface, the Neo4j Browser available at http://localhost:7474.
Just try it! There are some guides to get started within the browser, but more information can be found online.

If you don’t want to install it on your machine, you can always create a free instance on GrapheneDB, a Neo4j As A Service provider.

The Neoxygen Components

Neoxygen is a set of open-source components, most of them in PHP, for the Neo4j ecosystem available on Github. Currently, I’m the main developer. If you are interested in contributing as well, just ping me.

A powerful Client for the Neo4j HTTP-API is named NeoClient, with multi-database support and built-in high availabililty management.

Installation and configuration

The installation is trivial, just add the neoclient dependency in your composer.json file :

{
  "require": {
    "neoxygen/neoclient":"~2.1"
  }
}

You configure your connection when building the client :

use Neoxygen\NeoClient\ClientBuilder;

$client = ClientBuilder::create()
  ->addConnection('default', 'http', 'localhost', 7474)
  ->build();

If you created an instance on GrapheneDB, you need to configure a secure connection with credentials. This is done by appending true for using the auth mode and your credentials to the addConnection method :

<?php

use Neoxygen\NeoClient\ClientBuilder;

$connUrl = parse_url('http://master.sb02.stations.graphenedb.com:24789/db/data/');
$user = 'master';
$pwd = 's3cr3tP@ssw0rd';

$client = ClientBuilder::create()
  ->addConnection('default', $connUrl['scheme'], $connUrl['host'], $connUrl['port'], true, $user, $password)
  ->build();

You have now full access to your Neo4j database with the client connecting to the HTTP API.

The library provides handy methods to access the different endpoints. However, the most frequently used method is sending a Cypher query.

Handling graph results in a raw json response is a bit cumbersome. That’s why the library comes with a handy result formatter that transforms the response into node and relationship objects. The formatter is disabled by default, and you can enable it by just adding a line of code into your client building process :

$client = ClientBuilder::create()
  ->addConnection('default', 'http', 'localhost', 7474)
  ->setAutoFormatResponse(true)
  ->build();

Let’s build something cool

We’re going to build a set of User nodes and FOLLOWS relationships incrementally. Then, we’ll be able to query friend-of-a-friend information to provide friendship suggestions.

The query to create a User is the following :

CREATE (user:User {name:'Kenneth'}) RETURN user

The query is composed of 5 parts :

query-anatomy

  • The CREATE clause (in blue), indicating we want to create a new element.
  • The identifier (in orange), used to identify your node in the query
  • The label (in red), used to add the user to the User labelled group.
  • The node properties (in green), are specific to that node.
  • The RETURN clause, indicating what you want to return, here the created user.

You can also try to run that query in the Neo4j Browser.

No need to wait, let’s create this user with the client :

$query = 'CREATE (user:User {name:"Kenneth"}) RETURN user';
$result = $client->sendCypherQuery($query)->getResult();

You can visualize the created node in your browser (open the starred tab and run “Get some data”), or get the graph result with the client.

$user = $result->getSingleNode();
$name = $user->getProperty('name');

We will do the same for another user, now with query parameters. Query parameters are passed along with the query and it allows Neo4j to cache the query execution plan, which will make your further identical queries faster :

$query = 'CREATE (user:User {name: {name} }) RETURN user';
$parameters = array('name' => 'Maxime');
$client->sendCypherQuery($query, $parameters);

As you can see, parameters are embedded in {}, and passed in an array of parameters as second argument of the sendCypherQuery method.

If you look at the graph now, you’ll see the two User nodes, but they feel quite alone :( , no ?

Imgur

Creating relationships

In order to create the relationships between our nodes, we’ll use Cypher again.

$query = 'MATCH (user1:User {name:{name1}}), (user2:User {name:{name2}}) CREATE (user1)-[:FOLLOWS]->(user2)';
$params = ['user1' => 'Kenneth', 'user2' => 'Maxime'];
$client->sendCypherQuery($query, $params);

Some explanations :

We first match for existing users named Kenneth and Maxime (names provided as parameters), and then we create a FOLLOWS relationship between the two.

Kenneth will be the start node of the FOLLOWS relationship and Maxime the end node.
The relationship type will be FOLLOWS.

Looking at the graph again shows that the relationship has been created.

Imgur

Creating a bunch of users

Manually writing all the creation statements for a set of 100 users and the relationships would be boring.
I want to introduce a very useful tool called Graphgen (one of the Neoxygen components) for generating graph data with ease.

It uses a specification that is very close to Cypher to describe the graph you want.
Here we’re going to create a set of 50 users and the corresponding FOLLOWS relationships.

Go to http://graphgen.neoxygen.io , copy and paste the following pattern in the editor area, and click on Generate :

(user:User {login: userName, firstname: firstName, lastname: lastName} *50)-[:FOLLOWS *n..n]->(user)

Imgur

You can see that it automatically generates a graph with 50 users, the relationships, and realistic values for login, firstname and lastname. Impressive, no?

Let’s import this graph into our local graph database, click on Populate your database and use the default settings.

Imgur

In no time, the database will be populated with the data.

If you open the Neo4j browser, and run “Get some data” again, you can see all the user nodes and their relationships.

Imgur

Getting suggestions

Getting suggestions with Neo4j is simple, you just need to match one user, follow the FOLLOWS relationships to the other users, then for each found user, find the users they follow and return those that you do not follow already. The suggestion also must not be the user for whom we are looking for suggestions.

In a common application, there will be a login system and the user will be only allowed to see the users he is following. For the sake of this post which is introducing you Neo4j, you’ll be able to play with all the users.

Let’s write it in Cypher :

$query = 'MATCH (user:User {firstname: {firstname}})-[:FOLLOWS]->(followed)-[:FOLLOWS]->(suggestion)
WHERE user <> suggestion 
  AND NOT (user)-[:FOLLOWS]->(suggestion)
RETURN user, suggestion, count(*) as occurrence
ORDER BY occurrence DESC
LIMIT 10';
$params = ['firstname' => 'Francisco'];
$result = $client->sendCypherQuery($query, $params)->getResult();

$suggestions = $result->get('suggestion'); // Returns a set of nodes

If you run this query in the neo4j browser, you’ll get your first matched user and the suggestions :

Imgur

Conclusion

In this part:

  • You’ve discovered graph databases and Neo4j
  • You learned the basics of the Cypher Query Language
  • You’ve seen how to connect to and run queries on a Neo4j database with PHP

In a followup article we’ll use everything we’ve learned so far and make a real Neo4j powere Silex PHP application.

Frequently Asked Questions (FAQs) about Graph Databases, Neo4j, and PHP

How do I connect to Neo4j with PHP?

To connect to Neo4j with PHP, you need to use a PHP client or driver that supports Neo4j. One such client is the Neo4j-PHP-Client by GraphAware, which provides a comprehensive and flexible API for interacting with Neo4j. To use this client, you need to install it via Composer, a dependency manager for PHP. Once installed, you can create a connection to your Neo4j database by providing the necessary credentials and connection details.

What are the benefits of using Neo4j with PHP?

Neo4j is a graph database that excels at handling complex, interconnected data. When used with PHP, a popular server-side scripting language, it allows developers to build powerful, data-driven applications. The combination of Neo4j and PHP provides several benefits. Firstly, it enables efficient querying and manipulation of graph data, thanks to Neo4j’s powerful Cypher query language. Secondly, it allows for easy integration with existing PHP applications and frameworks. Lastly, it offers robust performance and scalability, making it suitable for large-scale, enterprise applications.

How do I execute Cypher queries in PHP?

To execute Cypher queries in PHP, you need to use a PHP client or driver that supports Neo4j, such as the Neo4j-PHP-Client by GraphAware. This client provides a method for executing Cypher queries and retrieving the results. You simply need to create a query object, specify your Cypher query as a string, and then execute the query using the client’s run method. The results can then be accessed and manipulated using the client’s result handling methods.

How do I handle errors and exceptions when using Neo4j with PHP?

When using Neo4j with PHP, errors and exceptions can be handled using PHP’s built-in error handling mechanisms. Most Neo4j PHP clients and drivers, including the Neo4j-PHP-Client by GraphAware, throw exceptions when an error occurs. These exceptions can be caught and handled using try-catch blocks. Additionally, you can use PHP’s error reporting functions to log errors and track down issues.

Can I use Neo4j with PHP frameworks like Laravel or Symfony?

Yes, you can use Neo4j with PHP frameworks like Laravel or Symfony. Most Neo4j PHP clients and drivers, including the Neo4j-PHP-Client by GraphAware, are designed to be framework-agnostic. This means they can be integrated with any PHP framework that supports Composer dependencies. Some frameworks may also have specific packages or bundles that provide additional integration features for Neo4j.

How do I install and configure the Neo4j PHP client?

The Neo4j PHP client can be installed using Composer, a dependency manager for PHP. Once installed, you can configure the client by providing the necessary connection details and credentials. These can be specified when creating a new client instance, or they can be set in your application’s configuration files if you’re using a PHP framework.

How do I model and store data in Neo4j?

In Neo4j, data is modeled as a graph, consisting of nodes and relationships. Nodes represent entities, while relationships represent connections between entities. Both nodes and relationships can have properties, which are key-value pairs that store additional information. To store data in Neo4j, you create nodes and relationships using the Cypher query language. You can then set properties on these nodes and relationships as needed.

How do I retrieve and manipulate data in Neo4j using PHP?

To retrieve and manipulate data in Neo4j using PHP, you use the Cypher query language. Cypher queries can be executed using a Neo4j PHP client or driver, such as the Neo4j-PHP-Client by GraphAware. The results of these queries can then be accessed and manipulated using the client’s result handling methods.

What are some best practices for using Neo4j with PHP?

Some best practices for using Neo4j with PHP include: using parameterized queries to prevent Cypher injection attacks; handling errors and exceptions properly to ensure application stability; using transactions for complex operations that involve multiple queries; and optimizing your Cypher queries for performance.

Where can I find more resources and documentation on using Neo4j with PHP?

More resources and documentation on using Neo4j with PHP can be found on the official Neo4j website, the GitHub repositories of Neo4j PHP clients and drivers, and various online developer communities and forums. These resources provide comprehensive guides, tutorials, and API references that can help you get started with Neo4j and PHP.