Skip to content

Latest commit

 

History

History
382 lines (286 loc) · 11.5 KB

neo4j-cypher.org

File metadata and controls

382 lines (286 loc) · 11.5 KB

Cypher Property Graph Query Language Demo with Neo4j

Property graph model

In the property graph model, data is represented using graphs with nodes and edges that both can have types (called labels) and can be associated with a map of name-value pairs (called properties). In this demo, we will look at Cypher, a declarative query and data definition language for property graphs. We will use Neo4j which implements this language.

Creating and manipulating graphs

Creating nodes and edges

MATCH (n)
DETACH DELETE n
  • the CREATE statement creates new nodes and edges. A single create statement can create multiple nodes and edges. The statement is finished with ;.

The syntax for creating a node is:

CREATE (nodeid:label { propertynameOne:'value1', ..., propertynameN:'valueN' });

Note that node ids are only valid within the scope of a single statement.

To create an edge:

CREATE (nodeidOne)-[:EDGE_LABEL] { propertynameOne:'value1', ..., propertynameN:'valueN' }->(nodeidTwo)
CREATE (matrix1:Movie { title : 'The Matrix', year : '1999-03-31' })
CREATE (matrix2:Movie { title : 'The Matrix Reloaded', year : '2003-05-07' })
CREATE (matrix3:Movie { title : 'The Matrix Revolutions', year : '2003-10-27' })
CREATE (keanu:Actor { name:'Keanu Reeves' })
CREATE (laurence:Actor { name:'Laurence Fishburne' })
CREATE (carrieanne:Actor { name:'Carrie-Anne Moss' })
CREATE (keanu)-[:ACTS_IN { role : 'Neo' }]->(matrix1)
CREATE (keanu)-[:ACTS_IN { role : 'Neo' }]->(matrix2)
CREATE (keanu)-[:ACTS_IN { role : 'Neo' }]->(matrix3)
CREATE (laurence)-[:ACTS_IN { role : 'Morpheus' }]->(matrix1)
CREATE (laurence)-[:ACTS_IN { role : 'Morpheus' }]->(matrix2)
CREATE (laurence)-[:ACTS_IN { role : 'Morpheus' }]->(matrix3)
CREATE (carrieanne)-[:ACTS_IN { role : 'Trinity' }]->(matrix1)
CREATE (carrieanne)-[:ACTS_IN { role : 'Trinity' }]->(matrix2)
CREATE (carrieanne)-[:ACTS_IN { role : 'Trinity' }]->(matrix3)

Deleting and updating graphs

We do not discuss this here. Have a look at https://neo4j.com/docs/cypher-manual/current/clauses/delete/ https://neo4j.com/docs/cypher-manual/current/clauses/set/.

Querying with Cypher

Pattern matching and specifying what to return

  • cypher is based on patterns that are matched against the graph specified in the MATCH clause
  • as side effects of matching patterns, variables specified in the pattern are bound to the nodes / edges matched against the pattern
  • the RETURN clause specified what should be returned
    • Cypher queries either return a table or a graph depending on what is specified in the RETURN clause
    • as in SQL * returns everything

Anatomy of a pattern

Matching nodes

A node pattern is specified as:

(variablename:label { propertynameOne:'value1', ..., propertynameN:'valueN' })

This pattern will match all nodes of type label that have a property propertynameOne with value value1, a property propertynameTwo with value value2, and so one. All elements are optional, so the most basic node pattern that matches any node in the database is:

()

Consider some more examples:

(x) // match any node and bind it to variable x
(x:LABEL) // match any node of type LABEL and bind it to variable x
(:LABEL) // match any node of type LABEL, but do not bind to to any variable
(x { name: 'XXX' }) // match any node that has a property name with value XXX and bind it to variable x

Note that a pattern can consist of multiple parts

(x:Movie), (y:Actor) // bind x to all movies and y to all actors

Matching edges and paths

Single edges

Such a pattern defines constraints on an edge and its end points. The general form is ()-[]->() where () are node patterns as described above and [] places restrictions on the edge and possibly binds it to a variable. For example, to find actors that acted in movies:

(a:Actor)-[r:ACTS_IN]->(movie:Movie)

To find actors that are playing role Neo in some movie:

(a:Actor)-[r:ACTS_IN { role="Neo" }]->(movie:Movie)

Note that the edges can be written in either direction:

(movie:Movie)<-[r:ACTS_IN { role="Neo" }]-(a:Actor)

It is also possible to match on multiple relationship types:

(movie:Movie)<-[r:ACTS_IN|DIRECTS_IN]-(a:Actor)
Paths

Patterns can also encode paths of arbitrary length. Using * paths of any length are matched. For example, to find movies that are connected somehow in the graph:

(movie:Movie)-[*]-(otherMovie:Movie)

It is also possible to specify that the path should be of a certain length or that the length of the path is between a lower and an upper bound.

(movie:Movie)-[*2]-(otherMovie:Movie) // movies connected to other movies with path of length 2
(movie:Movie)-[*1..4]-(otherMovie:Movie) // movies connected to other movies with paths of length 1 to 4

Other constraints on edges can be combined with path restrictions. For example, to movies that are direct or indirect sequels of another movie:

(movie:Movie)-[:SEQUEL_OF*]-(:Movie)

Paths can also be bound to variables like so:

p = (movie:Movie)-[:SEQUEL_OF*]-(:Movie)

Paths can also be bound to variables like so:

Specifying what is returns

Returning graphs

Returning * returns the subgraph consisting of all nodes and edges that are matched by the pattern declared in the MATCH clause. For example, to return all actors and the movies they acted in:

MATCH (actor)-[r:ACTS_IN]->(movie)
RETURN *

actedin.png

To return all actors and movies in the database:

MATCH (actor:Actor),
      (movie:Movie)
RETURN *

actorsandmovies.png

To return actors that played character Neo in

MATCH (a:Actor)-[r:ACTS_IN { role: "Neo" }]->(movie:Movie)
RETURN *

neoroles.png

MATCH p = (a:Actor { name: "Laurence Fishburne" })-[*2]-(b:Actor)
RETURN *

lauence.png

Returning tables

  • when only properties are selected in the RETURN clause then the result is a table
  • Let us return the name of actors that acted in some movie
match (actor)-[r:ACTS_IN]->(movie)
return actor.name
actor.name
Keanu Reeves
Keanu Reeves
Keanu Reeves
Laurence Fishburne
Laurence Fishburne
Laurence Fishburne
Carrie-Anne Moss
Carrie-Anne Moss
Carrie-Anne Moss
  • or the names of actors and the titles of movies they starred in and what their role was
MATCH (actor)-[r:ACTS_IN]->(movie)
RETURN actor.name, r.role, movie.title
actor.namer.rolemovie.title
Keanu ReevesNeoThe Matrix Revolutions
Keanu ReevesNeoThe Matrix Reloaded
Keanu ReevesNeoThe Matrix
Laurence FishburneMorpheusThe Matrix Revolutions
Laurence FishburneMorpheusThe Matrix Reloaded
Laurence FishburneMorpheusThe Matrix
Carrie-Anne MossTrinityThe Matrix Revolutions
Carrie-Anne MossTrinityThe Matrix Reloaded
Carrie-Anne MossTrinityThe Matrix

Filtering with WHERE

Like in SQL you can filter results using WHERE

MATCH (actor)-[r:ACTS_IN]->(movie)
WHERE actor.name = 'Keanu Reeves'
RETURN actor.name
actor.name
Keanu Reeves
Keanu Reeves
Keanu Reeves

Ordering with ORDER BY and limiting with LIMIT and SKIP

Using LIMIT you can restrict the number of answer that are returned.

MATCH (actor)-[r:ACTS_IN]->(movie)
WHERE actor.name = 'Keanu Reeves'
RETURN actor.name
LIMIT 1
actor.name
Keanu Reeves

With ORDER BY answer can be ordered.

MATCH (actor)-[r:ACTS_IN]->(movie)
RETURN actor.name
ORDER BY actor.name
actor.name
Carrie-Anne Moss
Carrie-Anne Moss
Carrie-Anne Moss
Keanu Reeves
Keanu Reeves
Keanu Reeves
Laurence Fishburne
Laurence Fishburne
Laurence Fishburne

With SKIP you can skip n results.

MATCH (actor)-[r:ACTS_IN]->(movie)
RETURN actor.name
ORDER BY actor.name
SKIP 3
LIMIT 3
actor.name
Keanu Reeves
Keanu Reeves
Keanu Reeves

Set operations

UNION

MATCH (n:Actor)
RETURN n.name AS name
UNION ALL
MATCH (n:Movie)
RETURN n.title AS name
name
Keanu Reeves
Laurence Fishburne
Carrie-Anne Moss
The Matrix
The Matrix Reloaded
The Matrix Revolutions

Aggregation

Aggregation functions in RETURN

We can apply aggregation functions in the RETURN clause

MATCH (n:Actor)
RETURN count(*)
count(*)
3

If the RETURN clause also contains non-aggregation functions, then these are consider to be group-by expressions.

MATCH (a:Actor)-[:ACTS_IN]->(:Movie)
RETURN a.name, count(*)
a.namecount(*)
Keanu Reeves3
Laurence Fishburne3
Carrie-Anne Moss3

Subqueries with WITH

The WITH clause allows an intermediate result to be specified that can then be fed into additional clauses, e.g., filtering after an aggregation as shown below. For more details see here.

MATCH (a:Actor)-[:ACTS_IN]->(:Movie)
WITH a, count(*) AS c
WHERE c > 2
RETURN a.name, c
a.namec
Keanu Reeves3
Laurence Fishburne3
Carrie-Anne Moss3