notexOPENOverview
Notex/Systems/The Cypher Query Language
04.09LESSON 09 OF 16 · 3 MIN READ

The Cypher Query Language

Always free to read

Cypher is a query language for property graphs, originally created for the Neo4j graph database and later developed into an open standard as openCypher. Besides Neo4j, Cypher is supported by Memgraph, KùzuDB, Amazon Neptune, Apache AGE (with storage in PostgreSQL), and others. This language is named after a character in the movie The Matrix and is not related to ciphers in cryptography.

Example 3-4 shows the Cypher query to insert the lefthand portion of Figure 3-6 into a graph database. The rest of the graph can be added similarly. Each vertex is given a symbolic name, like usa or idaho. That name is not stored in the database but used only internally within the query to create edges between the vertices, using an arrow notation: (idaho) -[:WITHIN]-> (usa) creates an edge labeled WITHIN, with idaho as the tail node and usa as the head node.

Example 3-4. A subset of the data in Figure 3-6, represented as a Cypher query

CREATE
  (namerica :Location {name:'North America',  type:'continent'}),
  (usa      :Location {name:'United States',  type:'country'  }),
  (idaho    :Location {name:'Idaho',          type:'state'    }),
  (lucy     :Person   {name:'Lucy' }),
  (idaho) -[:WITHIN ]-> (usa)  -[:WITHIN]-> (namerica),
  (lucy)  -[:BORN_IN]-> (idaho)

When all the vertices and edges of Figure 3-6 are added to the database, we can start asking interesting questions. For example, suppose we want to find the names of all the people who emigrated from the United States to Europe. We can do that by finding all the vertices that have a BORN_IN edge to a location within the US and a LIVING_IN edge to a location within Europe, and returning the name property of each of those vertices.

Example 3-5 shows how to express that query in Cypher. The same arrow notation is used in a MATCH clause to find patterns in the graph: (person) -[:BORN_IN]-> () matches any two vertices that are related by an edge labeled BORN_IN. The tail vertex of that edge is bound to the variable person, and the head vertex is left unnamed.

Example 3-5. A Cypher query to find people who emigrated from the US to Europe

MATCH
  (person) -[:BORN_IN]->  () -[:WITHIN*0..]-> (:Location {name:'United States'}),
  (person) -[:LIVES_IN]-> () -[:WITHIN*0..]-> (:Location {name:'Europe'})
RETURN person.name

The query can be read as follows:

  • Find any vertex (call it person) that meets both of the following conditions:

  • person has an outgoing BORN_IN edge to a vertex. From that vertex, you can follow a chain of outgoing WITHIN edges until eventually you reach a vertex of type Location, whose name property is equal to United States.

  • That same person vertex also has an outgoing LIVES_IN edge. Following that edge, and then a chain of outgoing WITHIN edges, you eventually reach a vertex of type Location, whose name property is equal to Europe.

  • For each such person vertex, return the name property.

There are several possible ways of executing the query. The description given here suggests that you start by scanning all the people in the database, examining each person’s birthplace and residence, and returning only those people who meet the criteria.

But equivalently, you could start with the two Location vertices and work backward. If there is an index on the name property, you can efficiently find the two vertices representing the US and Europe. Then you can proceed to find all locations (states, regions, cities, etc.) in the US and Europe, respectively, by following all incoming WITHIN edges. Finally, you can look for people who can be found through an incoming BORN_IN or LIVES_IN edge at one of the location vertices.

Progress is saved on this device.
KEEP EXPLORING

One note leads to another.

Back to the library →
⌕
Search across the entire library ⌘ K