Neo4j Blog

Neo4j 2.0.0-RC1 – Final preparations

WARNING: This release is not compatible with earlier 2.0.0 milestones . See details below.

The next major version of Neo4j has been under development for almost a year now, methodically elaborated and refined into a solid foundation. Neo4j 2.0 is now feature-complete. We’re pleased to announce the first Release Candidate build is available today.

With that feature-completeness in mind, let’s see what’s on offer…

Cypher Syntax – finishing touches

Two guiding principles of Cypher language design are readability and internal consistency. The basic syntax should be easy to understand, with little ambiguity about the intent of a query. This release has a number of changes that follow those principles, resulting in much nicer looking syntax, with more clear semantics.

MATCH with properties

Cypher CREATE and MERGE clauses can have patterns with properties in them, but that syntax wasn’t previously supported in the MATCH clause. Now you can include properties in any pattern. This makes simple queries more concise; a query like this:

MATCH (a:Person) WHERE a.name = “Joe” RETURN a

Can now be written like this:

MATCH (a:Person {name:”Joe”}) RETURN a

OPTIONAL MATCH

Sometimes your data isn’t all the same – you are looking for a core pattern, but some matches have additional detail attached. We call this additional detail ‘optional’ because it isn’t required to match the core pattern (a bit like an outer join in SQL).

Previously, we expressed optional details with optional relationships, using the -[?]-> syntax. However, this sometimes proved confusing. To resolve the ambiguity, Stefan Plantikow came up with an excellent solution: separate the concerns.

Everything in a MATCH is now required, so the ? operator has been removed. For optional patterns, use the new OPTIONAL MATCH , which either returns matching data, or null if nothing is found.

For example, you can write:

MATCH (a:Person)

OPTIONAL MATCH (a)-[:SPOUSE]->(b)

RETURN a, b

This will find all Person nodes. If a person has a spouse, Neo4j find them, otherwise b will be null . Lovely!

MERGE for relationships

Cypher has built-in support for ‘get-or-create’: with a single query you can find existing data, or create it if it’s missing. Since this is a common operation for any database, we wanted to make it work very well in Cypher. To get-or-create, you use MERGE for single nodes or MERGE for relationships (but not both at the same time). MERGE for relationships replaces the old CREATE UNIQUE clause.

For example, to get-or-create a relationship between two nodes:

MATCH (a:Person {name: “Joe”}), (b:Person {name: “Steve”})

MERGE (a)-[r:KNOWS]->(b)

RETURN r

Simpler syntax for MERGE ON MATCH and ON CREATE

When use a MERGE clause in your query, there are two possible outcomes: Neo4j will either find all existing matching data, or create entirely new data. The special sub-clauses ON MATCH and ON CREATE allow to you to distinguish between these outcomes.

We’ve simplified the syntax of the ON MATCH and ON CREATE clauses, removing the need to cite an identifier from the related MERGE pattern. Where you used to write:

MERGE (a:Person {name: “Joe”}) ON CREATE a SET a.created = {}

You can now write (dropping the ‘a’ in ON CREATE ):

MERGE (a:Person {name: “Joe”}) ON CREATE SET a.created = {}

NULL != NULL

We’ve changed the way Cypher handles null in important ways: Many expressions now return null for invalid arguments ( HEAD([]) , Slicing, e.g. [][1..3] ). We’ve embraced ternary logic by allowing null to be used as a “maybe” value in expressions with AND , OR , NOT meaning it’s easier to compute predicates when information (like property values) is missing.

Caution: manual upgrade between milestones

Data stores created with any previous milestone version can not be used with 2.0.0-RC1 unless a manual upgrade is performed . This is due to incompatible changes made to the store files. Please proceed with caution, backing up your data before attempting to manually upgrade.

Manual upgrade (only from 2.0.0-M06, and after you’ve backed up):

Cleanly shut down on the old version on Neo4j 2.0.0-M06 $ bin/neo4j stop

Navigate to the database directory $ cd data/graph.db

Delete the label scan store (this is the critical part that has a new format). It will be recreated on startup. $ rm -rf schema/label

Start with the new version of Neo4j 2.0.0-RC1 $ bin/neo4j start

To be clear: DO NOT USE THIS RELEASE WITH EXISTING DATA Of course, as always you can safely upgrade between GA versions like 1.9.5 and the coming 2.0.0.

Breaking changes

While this release is feature complete, there are some breaking changes since milestone 6.

Breaking changes include:

textual status codes, which alter the error response from the transactional endpoint

Next steps

Now that the Release Candidate is ready, we’d love for you to try it out. Between now and the GA release, we will only be including bug fixes. Give us feedback about any issues you might encounter, reporting problems on our google group and asking questions on Stack Overflow .

Hi Jan!<br /><br />It was necessary for the new 2.0 syntax, as the old ? operator relied on the presence of the START clause to determine which end of the pattern was optional. Without having a START clause, we can&#39;t work that out anymore.<br /><br />However, you can always prefix your queries with &#39;CYPHER 1.9 &#39;, and you&#39;ll be able to continue using the same queries as before

The shortestPath function is only returning 16 nodes at a time, no matter where in the graph I start. Is this a bug?<br /><br />Here is the query:<br /><br />START s=node(0), n=node(*) <br />MATCH p=shortestPath((s)-[*]-&gt;(n:label)) <br />RETURN length(p), id(n), n.property<br />ORDER BY length(p) asc