Cypher Language
Cypher is the most widely use query language for interacting with data in a property graph format. It is structurally and syntactically similar to SQL, with the main difference being the MATCH
clause. The idea of MATCH
is to focus on declaratively describing the graph shape (pattern) that you want and then to let the query compiler pick a good execution plan. What would normally require multiple JOIN
s in a relational model often just reduces to one MATCH
with a pattern that has multiple edges:
MATCH (n: Person)-[:has-parent]->(p: Person)-[:lives-in]->(c: City)
RETURN p.name AS name, c.name AS parentsCity
Compare the above Cypher to the equivalent SQL below:
SELECT n.name AS name, c.name AS parentsCity
FROM persons AS n
JOIN persons AS p ON n.parent = p.id
JOIN cities AS c ON p.city = c.id
Cypher queries are used in Quine for several purposes:
- Used to ingest events and create the graph
- Set as standing queries to find live matches from the dynamically changing graph
- Entered in the query bar of the Exploration UI
- Set as “quick queries” in the Exploration UI
- Sent directly through the REST API
Language Specification
The official OpenCypher language reference here.
Unsupported Language Features
Almost all of the Cypher language is supported with a few notable exceptions:
- Nodes found in a Cypher
MATCH
statement do not include updates made in the same query following the match statement. Some particular cases where this tends to be more surprising are:- When updating a node’s labels or properties with
SET n :MyLabel
,SET n.foo = "bar"
, orSET n += propertyMap
, then
variable representing the node will not reflect the update. - The same node can be aliased under two different names and those two aliases may be different if there have been intervening changes.
- When updating a node’s labels or properties with
- The identity of an edge in Quine is determined entirely by the direction, label, and endpoints of the edge. This has several implications:
- Edges do not have IDs. A query like
MATCH (n)-[e]->(m) RETURN id(e)
does not return a useful value. Looking up edges must be done from one of the nodes on either side. - There cannot be multiple edges with the same label and direction connecting the same two nodes. If a query such as
MATCH (n), (m) WHERE id(n) = idFrom(0) AND id(m) = idFrom(1) CREATE (n)-[:myEdge]->(m)
is run twice, the secondCREATE
will have no effect since the single possible edge already exists. - Properties on edges are not supported. Edges can always be equally represented as an
edge-node-edge
instead of just anedge
. The node in the middle becomes the carrier for properties that are about the relationship. Quine does not suffer from graph traversal challenges that sometimes motivate users to limit query length, so this node amplification is not problematic in Quine.
- Edges do not have IDs. A query like
- The runtime characteristics of setting a node label are exactly equivalent to using a property. Querying using labels does not enable more efficient scanning, it is just an additional filter condition. Even if there are only a handful of nodes with the
:Person
label on them, a query such asMATCH (p:Person) RETURN DISTINCT p.name
will still need to scan all nodes to find those with the desired:Person
label. DETACH DELETE
does not work on a path.shortestPath
andallShortestPaths
cannot be used inside aMATCH
/MERGE
pattern - they can only be used as expressions returning a path, or list of paths.- Some aggregation functions are not yet implemented:
percentileCont
,percentileDisc
,stDev
, andstDevP
. sum
andavg
do not work on durations.- Hints inside queries (an advanced Cypher feature) are not supported and are silently ignored.
- Cypher commands are not supported (used for system management in other systems).
Railroad Diagrams
Interactive railroad diagrams for the Cypher language syntax are a helpful in understanding query parts in Cypher.
Example: