NoSQL Zone is brought to you in partnership with:

Eric is the Editorial Manager at DZone, Inc. Feel free to contact him at Eric has posted 804 posts at DZone. You can read more from them at their website. View Full User Profile

Neo4j 1.8.M03 - Related Coffee

  • submit to reddit

The content of ths article was originally written by Andreas Kolleger over at the Neo4j blog.

Released today, Neo4j 1.8.M03 introduces the RELATE clause, a two-step dance of MATCH or CREATE. Also, new Transaction support in the shell let's 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.

Coffee Graph

Transactional Shell

Prior to this release, every query issued in 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.

Relate Yourself

Neo4j 1.8.M03 is available for immediate download in the usual places. Get it now:
  • Download from
  • 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.



Published at DZone with permission of its author, Eric Genesky. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)


Daniel Slazer replied on Tue, 2012/06/12 - 12:34pm

If Base had a field, say "int foo;" then another four bytes would be needed to hold that field. "new Base()" would reserve 12 bytes, and "new SubClass()" would also be 12 bytes. That extra four bytes for the int would be needed by objects of either class, because if you declare a field, you get a field (duh!) Even if you didn't use "foo" it would still be allocated, as compilers and runtimes are not (at present) clever enough to optimize away unused fields.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.