Subscribe to PHP Freaks RSS

Introducing the Neo4j Symfony Bundle

syndicated from www.sitepoint.com on August 4, 2017

There is no such thing as disconnected information, no matter where you look - people, events, places, things, documents, applications and the information about them is all heavily connected. As the volume of data grows, so does the number and dynamicity of its connections. And if you've tried in the past to store and query that highly connected, semi-structured data in any database, you probably experienced a lot of challenges.

Example graph

The Labeled Property Graph in a native Graph Database

Neo4j was built to handle exactly this real-world information without compromising on the number and types of connections you can have relating your entities. It is an open-source NoSQL database that uses the Labeled Property Graph to store the entities of your domain model (diagram) as Nodes and their connections as Relationships each of which can have arbitrary properties.

Nodes and releationships with properties

Neo4j is not just a graph layer on top of another database but a full blown, transactional (ACID) database with everything from managing pages of records on disk to providing a scalable, secure cluster. And as a native graph database it uses dedicated data structures to store and query highly connected data efficiently. Unlike in other databases, (complex) JOIN queries are not computed repeatedly at query time. Instead, relationships between entities are stored directly. During querying the database engine can use direct record-pointers for constant time lookups.

The open Cypher Query Language

This doesn't just extend to modeling or storage, even the Cypher graph query language that comes with Neo4j is focused around graph patterns, this time represented as ASCII-art in your query: (dan:Person {name:"Dan"})-[:LOVES]->(ann:Person {name:"Ann"}), which make your queries extremely readable even for non-developers, e.g. here is a recommendation query ("customers like you also bought this"):

MATCH (c:Customer)-[:BOUGHT]->(:Product)<-[:BOUGHT]-(o:Customer)-[:BOUGHT]->(reco:Product)
WHERE c.id = 123 AND NOT (c)-[:BOUGHT]->(reco)
RETURN reco.name, count(*) as frequency
ORDER BY frequency DESC LIMIT 10;

Symfony, a rapid development framework for PHP

Symfony is the role model of frameworks for modern PHP. The framework has a component approach and has been around for the last 11 years. From the Symfony ecosystem we’ve seen projects like Composer, Twig, Swiftmailer, Assetic, Monolog and many more. Thanks to the component approach, it has been made easy for other projects and frameworks to reuse code from Symfony. Projects like Laravel, Silex, Sylius, Drupal, phpBB, eZ are all using Symfony components.

A key factor of Symfony’s success is the flexibility of the framework in combination with the ease of use. The standard edition of Symfony comes with Doctrine as default database layer abstraction which supports some major databases like MySQL and MongoDB. But neither the database layer nor Doctrine is a primary citizen in Symfony. They could easily be replaced by something else.

Introducing Symfony Neo4j Bundle

To provide a smooth integration between Neo4j and Symfony we’ve created the SymfonyNeo4jBundle. It wraps the excellent PHP community client by Graphaware and creates a solid Symfony experience. Thanks to the WebProfiler integration, you will see all your database calls, all the queries and their results. You will even have a view over any exceptions that are thrown when interacting with the database. You will also get detailed statistics about each database call. This makes debugging your application way easier.

The bundle also integrates the client events with the Symfony event dispatcher. You could now create event subscribers that listen to the interactions with Neo4j e.g. for integration with MonologBundle to log all your database queries.

The bundle is not opinionated in how you are using Neo4j. Using the OGM is optional. Advanced Neo4j users will have full control over the client and what Cypher gets executed.

An API like Doctrine

For developers who are familiar with Doctrine, they will know how to use GraphAware’s OGM (Object Graph Mapper). The OGM has an EntityManager that implements Doctrine’s ObjectManager interface, which gives you functions like “find”, “remove”, “persist” and “flush”. Developers will have the exact same experience working with models from Neo4j’s OGM compared to Doctrine’s MySQL EntityManagers.

Configuration

Like in most modern frameworks, Symfony separates configuration from the code. This is good software practice which the Neo4jBundle adheres to. It provides the ability to easily configure multiple connections, multiple clients and multiple entity managers. For each connection you can decide if you want to use HTTP or the new binary “bolt” protocol.

Thanks to Symfony’s configuration component, you may use Yaml, XML or PHP to specify your configuration. The default configuration will set up one connection to 127.0.0.1:7474 with the defaults username / password.

Continue reading %Introducing the Neo4j Symfony Bundle%