Neo4j 1.8.M03 - Related Coffee
Join the DZone community and get the full member experience.
Join For FreeReleased back in 2012, Neo4j 1.8.M03 introduced the RELATE clause, a two-step dance of MATCH or CREATE. Also, new Transaction support in the shell lets you call for a do-over in case you misstep.
RELATE, a Subgraph Match-Maker
A RELATE clause looks a lot like a MATCH clause — the ASCII-art of graph traversals — but behaves differently when there isn't a satisfying subgraph. When there is no match, RELATE will create the needed Relationships and even intervening Nodes. RELATE ensures that the subgraph exists.
So, I just fetched myself a coffee. Let's say I want to keep track of how often I visit 3 Bees Coffee. I could carve notches on my desk, but I've already ruined one Ikea desk that way. Being graph-minded, I immediately realize that I'll be curious about deeper questions regarding all the places I visit. I will, of course, evolve a graph mini-app.
Neo4j 1.8.M01 introduced the CREATE clause, so I'll create me and the coffee shop:
CREATE me = {name:"Andreas"}, `3bees` = {name: "3 Bees Coffee"}
(Note the back ticks around 3bees because the term starts with a number)
To record that I have visited 3 Bees Coffee, I could add a relationship at the same time:
CREATE me = {name:"Andreas"}, `3bees` = {name: "3 Bees Coffee"}, me-[:VISITS]->`3bees`
Of course, I will be re-visiting coffee shops more often than going to newly opened shops. I already know about me, and will usually know about the coffee shop, so what I really want to do is just create the Relationship.
START me=node(1), coffee=node(2) CREATE me-[:VISITS]-coffee
Easy as pie. Mmm pie. Create a record for me, create a record for a shop, and whenever I visit a shop, create a Relationship. Because I want to keep track of the frequency of my visits, I suddenly have a problem: I don't want to create a Relationship every time, but get one if it exists and just update a property on it.
Cypher is declarative. There is no spoon, I mean 'IF'. So we turn to our friendly match-making RELATE clause:
START me=node(1), coffee=node(2) RELATE me-[v:VISITS]-coffee return v
That'll match the VISITS if it exists, or create one if it doesn't. To update the visits, I can convert the RETURN into a WITH to tack on a SET clause like so:
START me=node(1), coffee=node(2) RELATE me-[v:VISITS]-coffee WITH v SET v.visits=(v.visits +1) RETURN v
OK, one last detail to adjust: the classic initial condition problem. If RELATE happened to create a new Relationship, it won't yet have a visits Property. We'll use COALESCE to ignore v.visits if it is null, then add 1:
START me=node(1), coffee=node(3) RELATE me-[v:VISITS]-coffee WITH v SET v.visits=(coalesce(v.visits?,0)+1) return v
Ah, now I have even more motivation to take coffee breaks. The RELATE clause is powerful fun. Get yourself a cup of coffee, then sit down to peruse the Neo4j Manual section on Cypher RELATE to learn more. And, check on my coffee consumption in the Neo4j Live console, where you can play around with RELATE.
Transactional Shell
Prior to this release, every query issued in the Neo4j shell (whether command-line or in Webadmin) created a transaction when needed. Now, you have control over transactions with some new shell commands: begin transaction, commit, and rollback.
These let you practice your new Cypher dance moves without worrying about falling on your face and taking your database down with you. As usual, look to the Neo4j Manual for the details.
Now that we’ve looked back in time, let’s see what Neo4j can do better than SQL.
SQL is an impressive query language but there are things that Cypher handles so much better.
Whereas SQL started as a single table query language, support was added later for geospatial data and for XML and JSON as well. XML is primarily used for displaying documents on web pages. It uses customized markup languages that are user-defined. JSON reads data from web servers in order to display it online.
When dealing with relational databases which are built on tables, JOINs make the connections.
So how does this relate to Neo4j?
Well, Neo4j is designed to handle product recommendation engines as well as supply management and personalizing customer experience. And Cypher’s graph query language allows you to extract data from graphs. It’s essentially SQL for graphs.
Cypher is easy to use and understand. It’s designed for graphs.
It borrows from other languages such as Python and is a powerful, full-featured modern language perfect for data analysts and subject matter experts who need to extract meaningful data by reading and writing queries themselves if need be.
You don’t need to be a developer to get the benefits from Cypher.
A feature of graph databases is that their searches are schema-free. Or at least optional.
By not having a fixed schema you can develop the relationships, add attribute types and develop your data as you go. This provides extreme levels of flexibility when developing applications.
SQL Path Patterns Query
Using path patterns which is an advanced feature, you can have a product that points to a list of categories. With a deep hierarchy, one which you don’t know the depth of yet, you can insert a “*” to find arbitrary linked relationships right to the root directory.
But you can limit it to a set number of relationships as well as categories. This is all easily achieved in Cypher but requires linking together a chain of queries in SQL. Each level must be spelled out in the query to the limit that is needed.
A cumbersome and time-intensive process, especially when you don’t necessarily know how many categories you’re going to end up with anyway.
Find All Cycles in a Directed Graph
If you wish to find loops, where a loop leads back to the same person or thing over again, path patterns will determine the outcome.
Using MATCH path = (p:Person)-[*3..10]-(p), one can look for 5 hops ending with the person you started with. Not only is the data available in a table but it can be generated visually.
And that in essence is what you get with Cypher; a powerful much more user-friendly tool that is purpose-built to provide graph queries in a format that the user can manipulate to show relationships without being bogged down in endless hours of programming and validation.
Combine Reads and Writes
If you’re familiar with SQL, you need to support Reads and Writes by using insert statements or insert from select. Unfortunately, that’s where it ends.
Cypher does the heavy lifting and combines reads and writes in a single query. So, you can update the database while simultaneously fetching data.
The benefits of Cypher over SQL don’t end there but I’m sure you get the point.
Relate Yourself
Neo4j 1.8.M03 is available for immediate download in the usual places. Get it now:
- Download from neo4j.org
- Bump the versions in your maven pom.xml
- Provision on heroku with: heroku addons:add neo4j --neo4j-version 1.8.M03
Want to practice Cypher with fellow Graphistas? Join us at a meetup somewhere in the world, or propose a new location and we'll look into visiting your area to buy you a cup of coffee.
The content of this article was originally written by Andreas Kolleger over at the Neo4j blog.
Opinions expressed by DZone contributors are their own.
Comments