Posts

NULLS in Neo4j

From the documentation NULLs in Neo4j are explained as. null is used to represent missing/undefined values. null is not equal to null . Not knowing two values does not imply that they are the same value. So the expression null = null yields null and not true . To check if an expression is null , use IS NULL . Arithmetic expressions, comparisons and function calls (except coalesce ) will return null if any argument is null . An attempt to access a missing element in a list or a property that doesn’t exist yields null . In OPTIONAL MATCH clauses, null s will be used for missing parts of the pattern. All very neat and dry and abstract. NULLS are undefined, they have no value that can be determined. In Neo4j, only non-null properties are stored. A different concept to the traditional database way of looking at the world. Each Node, of the same label, can have entirely different properties, and will have null return values where no determinable value for a property has been...

Neo4j WITH Clause

WITH allows you to pass on data from one part of the query to the next. Whatever you list in WITH will be available in the next query part. You can use aggregation, SKIP, LIMIT, ORDER BY with WITH much like in RETURN. The only difference is that your expressions have to get an alias with AS alias to be able to access them in later query parts. That means you can chain query parts where one computes some data and the next query part can use that computed data. In your case it is what GROUP BY and HAVING would be in SQL but WITH is much more powerful than that. here is another example match (n:Employee)-[r1:WORKSIN]->(a:Team) with distinct a order by a.name limit 10 match (a)-[:INBUILDING]->(c:Property) return c.name WITH is just like RETURN just within a query. it can select, aggregate, limit, sort it's arguments. The only difference is that you need to name each expression. Any after the WITH statement only the values / variables that are passed along are accessible/visible. ...

Updating a Property on a Highly Accessed Node

There may be a time where many user sessions attempt to update the same property on the same node. Unlikely, but possible. This may be a 'sequence' node, where you're keeping track of an increasing identifier, a sort of autoincrement. How can you be, almost, certain that your CYPHER statement will not be blocked by another session updating the node property at that exact time? Assume the sequence node: CREATE (s:Sequences {counterToIncrement: 0}) Then call the following CYPHER MATCH (s:Sequences) CALL apoc.atomic.add(s,'counterToIncrement',1,10) YIELD newValue as seq RETURN seq This will attempt to add 1 to the sequence property 'counterToIncrement' , and will attempt up to 10 times if the property is locked, and finally the new value of 'counterToIncrement' is yielded and returned. From a post : https://community.neo4j.com/t5/neo4j-graph-platform/integer-sequence-generator-in-neo4j-apoc/td-p/19403  

What is a Node

A Node is the 'Table' of the Graph Database world.   The main entity in a graph. They are also sometimes referred to as vertices or points. In our ASCII art world, a pair of parentheses is used to represent nodes. This resembles a circle and provides a simplified syntax for representing a node in ASCII:     ()     (node) The variable (node) holds node values so they can be processed or returned in a query later on. If you do not need to do anything with the node, you can skip the use of the variable. 

MERGE made a new Node

MERGE is a powerful and misunderstood component of the CYPHER toolbox. Assume you have two :Person nodes each with a name property ('Adam' and 'Bob'). You might assume that you could MERGE as follows to create a [:KNOWS] relationship: MERGE (a:Person {name:'Adam'})-[r:KNOWS]->(b:Person {name:'Bob'}); and you'd be correct, it works perfectly Always remember MERGE is based on matching the entire pattern in the statement. Say you now want to set the age of Adam to 21 in the same statement. You might think it's as simple as MERGE (a:Person {name:'Adam',age:21})-[r:KNOWS]->(b:Person {name:'Bob'}); will create 2 new Person nodes and a [:KNOWS] relationship. If there is a unique constraint on :Person (name) there will be errors thrown and no new nodes or relationships. Why, the initial part of the MERGE 'looks' for a pattern match on the :Person node of name:'Adam' and age:21, it doesn't create a property. No m...

Delete Nodes Without Labels.

Delete nodes without labels MATCH (n) WHERE size(labels(n)) = 0 DETACH DELETE n Similarly you can find nodes without labels using: MATCH (n) WHERE size(labels(n)) = 0 RETURN n

Removing Duplicate Relationships

From Neo4j v3.5 and onwards you can use a generic CYPHER statement: match (s)-[r]->(e) with s,e,type(r) as typ, tail(collect(r)) as coll foreach(x in coll | delete x) to remove all duplicate relationships in your Neo4j Graph Database. You can refine the control over what is deleted by adding in a node label or relationship type. We're collecting the relationships and grouping by type (as well as start and end node), so if any collection is greater than 1, then there are multiple relationships with the same type. TAIL removes the first element from the collect statement, but the first relationship back into rows then delete them. If you don't have labels to use for your query, then the query will be graph-wide, which is likely to take much longer to execute, and may encounter issues if the set of relationships to delete is too large to handle all at once.