shacl2cypher
← Shapes for Property Graphs

1. Why shapes for a property graph

Your graph already has rules. They're just scattered. This chapter explains what SHACL is, why a standard from the RDF world is a good home for those rules, and the few words you need for the rest of the book.

The rules you already have

Think about the HR graph from the introduction. Nobody wrote it down, but everyone on the team knows that:

  • every person has a name, and exactly one;
  • a person works for at most one company, and that thing really is a :Company;
  • an age is a whole number between 0 and 130;
  • a project ends after it starts;
  • every team has at least one manager among its members.

Where do those rules live today? Some are in application code, often in more than one service. Some are database constraints: Neo4j can enforce uniqueness and, in Enterprise Edition, existence and property types; LadybugDB enforces column types but has no NOT NULL outside the primary key. A few live in a Cypher query someone runs when a dashboard looks wrong. None of these places can tell you which nodes break which rule right now.

What SHACL is

SHACL, the Shapes Constraint Language, is a W3C Recommendation from 2017 for describing what valid data looks like. You write shapes; a validator checks data against them and produces a report of every violation.

Three properties make it a good fit for graph rules:

  • It is declarative. You say "a person has exactly one name". You don't write the query that finds people without one.
  • It is closed-world validation. A missing name is a violation, not an unknown fact. That is the meaning you want for a database schema. (OWL, the other famous RDF standard, is open-world: it would infer that the name exists somewhere, unknown. That is why OWL is the wrong tool for this job.)
  • It is a standard. Other teams, tools and validators already read it. A shapes file outlives any one codebase.

The catch, and the bridge

SHACL was designed for RDF, where everything is a triple: subject, predicate, object. Your graph is a labeled property graph. The two models are close enough to translate:

RDF, as SHACL sees itYour property graph
A resource with an IRI, e.g. ex:annA node, identified by a key property such as id
ex:ann rdf:type ex:PersonThe node has the label :Person
ex:ann ex:name "Ann", a literal valueThe property name: "Ann"
ex:ann ex:worksFor ex:acme, a resource valueThe relationship (ann)-[:WORKS_FOR]->(acme)
Several triples with the same predicateA list property, or several relationships
(nothing)Properties on a relationship
Language tags, blank nodes(nothing)

shacl2cypher is the bridge. You write standard SHACL as if your graph were RDF. It maps classes to labels and predicates to properties or relationships, then compiles every constraint into a read-only Cypher query that finds the violations. Where the translation is ambiguous, small s2c: annotations make it exact; other SHACL tools ignore them.

Words used in this book

shape
A set of constraints with a name. A node shape describes a kind of node; a property shape describes the values reached through one path.
target
What a shape applies to, for example "every node labelled :Person".
focus node
One node (or, with shacl2cypher, one relationship) being checked against a shape.
path
How to get from the focus node to the values being checked: a property, a relationship, or a chain of them.
value nodes
The values a path reaches from one focus node. Might be zero, one or many.
constraint
One condition inside a shape, e.g. sh:minCount 1. shacl2cypher compiles each one into a separate named rule.
violation
A focus node, and usually a value, that fails a constraint. Each one is a row in the report.

Takeaways

  • SHACL describes valid data declaratively, with closed-world meaning, the same meaning as a database schema.
  • RDF classes map to labels, literal predicates to properties, resource predicates to relationships.
  • shacl2cypher compiles each constraint into a read-only query and reports violations with the node and value at fault.