From 097cd60e490bae3b2ed3d033c3c8877e3245b939 Mon Sep 17 00:00:00 2001 From: Boris Verkhovskiy Date: Sat, 20 Apr 2024 09:05:03 -0700 Subject: [cypher/en] proofread --- cypher.html.markdown | 164 ++++++++++++++++++++------------------------------- 1 file changed, 63 insertions(+), 101 deletions(-) (limited to 'cypher.html.markdown') diff --git a/cypher.html.markdown b/cypher.html.markdown index 5fe113a2..f6febb4c 100644 --- a/cypher.html.markdown +++ b/cypher.html.markdown @@ -5,84 +5,57 @@ contributors: - ["Théo Gauchoux", "https://github.com/TheoGauchoux"] --- -Cypher is the Neo4j’s query language to manipulate graphs easily. It reuses syntax from SQL and mixes it with kind of ascii-art to represent graphs. +Cypher is Neo4j's query language for easily manipulating graphs. +It reuses syntax from SQL and mixes it with kind of an ASCII-art to represent graphs. This tutorial assumes that you already know graph concepts like nodes and relationships. -[Read more here.](https://neo4j.com/developer/cypher-query-language/) +## Nodes represent a record in a graph +`()` is an empty *node*, to indicate that there is a *node*, but it's not relevant for the query. -Nodes ---- - -**Represents a record in a graph.** - -`()` -It's an empty *node*, to indicate that there is a *node*, but it's not relevant for the query. - -`(n)` -It's a *node* referred by the variable **n**, reusable in the query. It begins with lowercase and uses camelCase. - -`(p:Person)` -You can add a *label* to your node, here **Person**. It's like a type / a class / a category. It begins with uppercase and uses camelCase. +`(n)` is a *node* referred by the variable `n`, reusable in the query. It begins with lowercase and uses camelCase. -`(p:Person:Manager)` -A node can have many *labels*. +`(p:Person)` - you can add a *label* to your node, here `Person`. It's like a type/class/category. It begins with uppercase and uses camelCase. -`(p:Person {name : 'Théo Gauchoux', age : 22})` -A node can have some *properties*, here **name** and **age**. It begins with lowercase and uses camelCase. +`(p:Person:Manager)` - a node can have many *labels*. -The types allowed in properties : +`(p:Person {name : 'Théo Gauchoux', age : 22})` - a node can have some *properties*, here `name` and `age`. It begins with lowercase and uses camelCase. - - Numeric - - Boolean - - String - - List of previous primitive types +The types allowed in properties: -*Warning : there isn't datetime property in Cypher ! You can use String with a specific pattern or a Numeric from a specific date.* +- Numeric +- Boolean +- String +- List of previous primitive types -`p.name` -You can access to a property with the dot style. +*Warning: there's no datetime properties in Cypher! You can use a String with a specific pattern or a Numeric from a specific date.* +`p.name` - you can access a property with the dot style. -Relationships (or Edges) ---- - -**Connects two nodes** - -`[:KNOWS]` -It's a *relationship* with the *label* **KNOWS**. It's a *label* as the node's label. It begins with uppercase and use UPPER\_SNAKE\_CASE. +## Relationships (or Edges) connect two nodes -`[k:KNOWS]` -The same *relationship*, referred by the variable **k**, reusable in the query, but it's not necessary. +`[:KNOWS]` is a *relationship* with the *label* `KNOWS`. It's a *label* as the node's label. It begins with uppercase and use UPPER\_SNAKE\_CASE. -`[k:KNOWS {since:2017}]` -The same *relationship*, with *properties* (like *node*), here **since**. +`[k:KNOWS]` - the same *relationship*, referred by the variable `k`, reusable in the query, but it's not necessary. -`[k:KNOWS*..4]` -It's a structural information to use in a *path* (seen later). Here, **\*..4** says "Match the pattern, with the relationship **k** which be repeated between 1 and 4 times. +`[k:KNOWS {since:2017}]` - the same *relationship*, with *properties* (like *node*), here `since`. +`[k:KNOWS*..4]` is structural information to use in a *path* (seen later). Here, `\*..4` says "Match the pattern, with the relationship `k` which can be repeated between 1 and 4 times. -Paths ---- - -**The way to mix nodes and relationships.** +## Paths - the way to mix nodes and relationships. -`(a:Person)-[:KNOWS]-(b:Person)` -A path describing that **a** and **b** know each other. +`(a:Person)-[:KNOWS]-(b:Person)` - a path describing that `a` and `b` know each other. -`(a:Person)-[:MANAGES]->(b:Person)` -A path can be directed. This path describes that **a** is the manager of **b**. +`(a:Person)-[:MANAGES]->(b:Person)` - a path can be directed. This path describes that `a` is the manager of `b`. -`(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)` -You can chain multiple relationships. This path describes the friend of a friend. +`(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)` - you can chain multiple relationships. This path describes the friend of a friend. -`(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)` -A chain can also be directed. This path describes that **a** is the boss of **b** and the big boss of **c**. +`(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)` - a chain can also be directed. This path describes that `a` is the boss of `b` and the big boss of `c`. -Patterns often used (from Neo4j doc) : +Commonly used patterns (from Neo4j documentation): -``` -// Friend-of-a-friend +```cypher +// Friend-of-a-friend (user)-[:KNOWS]-(friend)-[:KNOWS]-(foaf) // Shortest path @@ -91,17 +64,15 @@ path = shortestPath( (user)-[:KNOWS*..5]-(other) ) // Collaborative filtering (user)-[:PURCHASED]->(product)<-[:PURCHASED]-()-[:PURCHASED]->(otherProduct) -// Tree navigation +// Tree navigation (root)<-[:PARENT*]-(leaf:Category)-[:ITEM]->(data:Product) ``` - -Create queries ---- +## Create queries Create a new node -``` +```cypher CREATE (a:Person {name:"Théo Gauchoux"}) RETURN a ``` @@ -110,52 +81,51 @@ RETURN a Create a new relationship (with 2 new nodes) -``` +```cypher CREATE (a:Person)-[k:KNOWS]-(b:Person) RETURN a,k,b ``` -Match queries ---- +## Match queries Match all nodes -``` +```cypher MATCH (n) RETURN n ``` Match nodes by label -``` +```cypher MATCH (a:Person) RETURN a ``` Match nodes by label and property -``` +```cypher MATCH (a:Person {name:"Théo Gauchoux"}) RETURN a ``` Match nodes according to relationships (undirected) -``` +```cypher MATCH (a)-[:KNOWS]-(b) RETURN a,b ``` Match nodes according to relationships (directed) -``` +```cypher MATCH (a)-[:MANAGES]->(b) RETURN a,b ``` Match nodes with a `WHERE` clause -``` +```cypher MATCH (p:Person {name:"Théo Gauchoux"})-[s:LIVES_IN]->(city:City) WHERE s.since = 2015 RETURN p,state @@ -163,19 +133,17 @@ RETURN p,state You can use `MATCH WHERE` clause with `CREATE` clause -``` +```cypher MATCH (a), (b) WHERE a.name = "Jacquie" AND b.name = "Michel" CREATE (a)-[:KNOWS]-(b) ``` - -Update queries ---- +## Update queries Update a specific property of a node -``` +```cypher MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p.age = 23 @@ -183,7 +151,7 @@ SET p.age = 23 Replace all properties of a node -``` +```cypher MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p = {name: "Michel", age: 23} @@ -191,27 +159,25 @@ SET p = {name: "Michel", age: 23} Add new property to a node -``` +```cypher MATCH (p:Person) WHERE p.name = "Théo Gauchoux" -SET p + = {studies: "IT Engineering"} +SET p += {studies: "IT Engineering"} ``` Add a label to a node -``` +```cypher MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p:Internship ``` - -Delete queries ---- +## Delete queries Delete a specific node (linked relationships must be deleted before) -``` +```cypher MATCH (p:Person)-[relationship]-() WHERE p.name = "Théo Gauchoux" DELETE relationship, p @@ -219,17 +185,17 @@ DELETE relationship, p Remove a property in a specific node -``` +```cypher MATCH (p:Person) WHERE p.name = "Théo Gauchoux" REMOVE p.age ``` -*Pay attention to the `REMOVE`keyword, it's not `DELETE` !* +*Pay attention to the `REMOVE` keyword, it's not `DELETE`!* Remove a label from a specific node -``` +```cypher MATCH (p:Person) WHERE p.name = "Théo Gauchoux" DELETE p:Person @@ -237,32 +203,28 @@ DELETE p:Person Delete entire database -``` +```cypher MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n, r ``` -*Seriously, it's the `rm -rf /` of Cypher !* +*Seriously, it's the `rm -rf /` of Cypher!* +## Other useful clauses -Other useful clauses ---- +`PROFILE` - before a query, show its execution plan. -`PROFILE` -Before a query, show the execution plan of it. +`COUNT(e)` - count entities (nodes or relationships) matching `e`. -`COUNT(e)` -Count entities (nodes or relationships) matching **e**. +`LIMIT x` - limit the result to the first `x` results. -`LIMIT x` -Limit the result to the x first results. +## Special hints +- Cypher only has single-line comments, using double-slashes: `// comment` +- You can execute a Cypher script stored in a .cql file directly in Neo4j (it's an import). However, you can't have multiple statements in this file (separated by `;`). +- Use the Neo4j shell to write Cypher, it's really awesome. +- Cypher will be the standard query language for all graph databases (known as [openCypher](https://opencypher.org/)). -Special hints ---- +Read more [here](https://neo4j.com/developer/cypher-query-language/). -- There is just single-line comments in Cypher, with double-slash : // Comments -- You can execute a Cypher script stored in a **.cql** file directly in Neo4j (it's an import). However, you can't have multiple statements in this file (separated by **;**). -- Use the Neo4j shell to write Cypher, it's really awesome. -- The Cypher will be the standard query language for all graph databases (known as **OpenCypher**). -- cgit v1.2.3