Saturday, May 26, 2012

Neo4j 1.8.M03 - Related Coffee

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 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.

Cheers,
Andreas

Tuesday, May 15, 2012

Neo4j 1.8.M02 - The Strong, Silent Type


Our longer arcs of development are chunked up into short-term stories, which arrive with notable features at differing points. Uniquely, at this 1.8.M02 merge point, the changes are all of the strong, silent type: under-the-hood improvements, stage-setting additions, or simple issue-correcting.

This is a solid, trustworthy release for anyone staying up-to-date with the leading edge of development. Go get download Neo4j 1.8.M02 to keep up. If you're on Heroku, you can simply specify the version when provisioning a new database:
# heroku addons:add neo4j --neo4j-version 1.8.M02
Got questions? Ask us on Stack Overflow. Want to exchange some ideas? Let's chat on our Google Group.

Cheers,
Andreas

Thursday, May 10, 2012

Graph This - rendering your graph with Graphviz.

Triggered by a user question, let me just very briefly highlight a nice and easy graph visualization feature.

Sometimes, you just want to fast see what you are putting in your little example graph. In Neo4j, there is a well hidden gem-the Graphviz Component. To very shortly output a graphviz rendering, look at this test, demonstrating the basic usage (this code is actually taking a traversal instruction to walk the graph, you can easily just use the whole graph):









And gives you the following output in the Graphviz DOT notation: With this piped into a file, say neo4j.dot, you can now do (after installing graphviz and dot on your machine):

dot -Tpng -O neo4j.dot


And get an output file of neo4j.dot.png, pictured below.






















Voila, your are done and can see what you just programmed!


Happy hacking!


/peter

Thursday, May 3, 2012

Neo4j 1.8.M01 Release - Vindeln Vy

Neo4j 1.8 has an eye for expansive views, painting a picture with data and hanging it on the web. In this first milestone release, artful work on the Cypher query language is complemented with live views in the Neo4j documentation.

Cypher CREATE, SET, DELETE, FOREACH


Lead Cypherologist Andrés Taylor has been cranking out work like Pablo Picasso with an empty museum. He shared some of his thoughts about the new Cypher grammar available in 1.8.M01:

ABK: It seems you can't get Cypher out of your head fast enough.
AT: Yeah, it’s really like that. My family is tired of listening to me talk over the dinner table about implementation details about Cypher, I just can’t let it go.

ABK: Some of Cypher is SQL inspired, showing your SQL roots, but the new grammar is not like SQL.
AT: At first, I didn’t want any mutation stuff in it whatsoever, it was going to be a read only language. Then, I didn’t know what I wanted, but I did know what I didn’t want. Like with SQL, with all the problems you can have with inserting data.

ABK: What kind of problems?
AT: I think that SQL is a wonderful language when you’re talking about SELECT statements, but when you’re doing data manipulation, it quickly breaks down into an imperative thing. For example a normal problem is the “insert or update", which doesn’t have any clean solution. Another is working over collections of stuff.

ABK: Ah, so that’s why FOREACH is included now.
AT: Yup.
ABK: And so what was your solution?
AT: Being declarative. By giving our users the tools to express what they want in a declarative way so they don’t have to invent patterns to work around the language. And, it is much, much easier to understand what’s happening, for a reader of a query.

AT: Looking at a problem, a bug yesterday, I needed a graph to work on so I wrote:
CREATE a,b, a-[:x]->b, a-[:y]->b;
Try It
Just two nodes, with two relationships between them, and that was awesome. Actually, the first version of this would have looked to much worse. There has been fine-tuning. There was a meetup, when Aseem came with a lot of suggestions and the community had a lot of discussion about it. This is the result.
Continuing with the example, you can give them values, with a JSON look-alike thingy:
CREATE a={name:"Andres", age:37}, b, a-[:x { foo:"bar" } ]->b, a-[:y]->b
Try It
Then update a property like this:
START n=node(0) SET n.name="Michael";
Try It
Simple deletes are now possible like this:
START n=node(0) DELETE n;
Try It

ABK: What about more complex statements, like operations on a subgraph?
AT: Instead of sub-queries, you can chain parts of statements using WITH, which essentially combines a RETURN and a START. Like this:
START lucy=node(1) MATCH lucy-->movie
    WITH lucy, collect(movie.title) AS movies
    SET lucy.movies = movies
Try It
To work on that collections of things, there is FOREACH:
START lucy=node(1) MATCH lucy-->movie WITH lucy, collect(movie) AS movies 
    FOREACH (movie in movies : SET movie.actress=lucy.name )
Try It

The one rule that we have, is that in one part of the query you can only read from the graph or write to the graph. In the short forms above, there are two logical parts, a write then a read, with an implied separation. To be explicit, and create longer queries from parts, you use WITH.


ABK: Neat. Well, thanks for all the hard work Andrés. Can't wait to try it out.
AT: There is more to come, but this feels good.  Enjoy.

Hogwarts Manual of Graphs

Having unleashed the live Graph Console, the obvious next step was to animate the Cypher examples in the Neo4j Manual. Now the same graph code that generates the documentation also creates interactive consoles to allow experimentation. As a living, constantly evolving document, the Neo4j Manual learns new ways to help you learn.

The Console itself is evolving into a nice REPL, currently supporting Cypher and Geoff for initial graph creation, and Cypher for queries. A nice touch is that the visualization now highlights created nodes and relationships. When done, the graph and an initial query can be shared with a click of the share-button.
These shared graph-gists are really handy for tweeting questions, reporting issues on github and discussing graph modeling in the Neo4j Google Group.

Details

Other changes of note included in this release are:
  • an OSGi section has been added to the manual
  • streaming results from the REST API
  • the usual relentless performance improvements and bug fixes
You can read all the details in the CHANGES.TXT

Enjoy the View

The 1.8 development branch is off to a promising start. Get it today and give us feedback about the direction we're headed. Heroku users, you'll be able to use 1.8.M01 by provisioning Neo4j like this:

# heroku addons:add neo4j --neo4j-version 1.8.M01

As always, thanks to all of you for your feedback. Join us on the google group for discussions, and ask questions on Stack Overflow with tag neo4j.

Cheers,
The Neo4j Team