284 lines
6.4 KiB
Markdown
Executable File
284 lines
6.4 KiB
Markdown
Executable File
---
|
|
gitea: none
|
|
include_toc: true
|
|
---
|
|
# Cypher
|
|
|
|
## Queries
|
|
|
|
- A Node can have Properties and Labels
|
|
- A Relationship can have Properties and Types.
|
|
|
|
### delete whole db content
|
|
|
|
``` graphql
|
|
MATCH (n) detach delete n;
|
|
```
|
|
|
|
### Nodes
|
|
|
|
#### Create
|
|
|
|
Create a node with label "Student" and properties name, age and nicknames (as array).
|
|
|
|
```
|
|
CREATE (n :Student {name:"Jack",age:22,nicknames:["Jacko", "Jackie"]});
|
|
```
|
|
|
|
#### Merge
|
|
|
|
`Merge` erstellt wie `Create` ein neuer Node. Wenn der Node aber schon existiert, geschieht nichts, im Gegensatz zu `Create`, wo ein zweiter Node erstellt wird. `Merge` kann auch verwendet werden, um zusätzliche Properties hinzu zu fügen. Entweder, wenn der Node schon existiert, oder zusammen mit der Neuerstellung, falls der Node noch nicht existiert.
|
|
|
|
Hier wird, falls der Node existiert, `nicknames` überschrieben (falls diese Property vorhanden ist)
|
|
|
|
```
|
|
MERGE (n :Student {name:"Jack",age:22})
|
|
SET n.nicknames=["J"];
|
|
```
|
|
|
|
oder explizit
|
|
|
|
```
|
|
MERGE (n :Student {name:"Jack",age:22})
|
|
ON MATCH SET n.nicknames=["J"];
|
|
```
|
|
|
|
Soll `nicknames` nur hinzugefügt werden, wenn der Node noch nicht existiert, dann so:
|
|
|
|
```
|
|
MERGE (n :Student {name:"Jack",age:22})
|
|
ON CREATE SET n.nicknames=["J"];
|
|
```
|
|
|
|
kombiniert:
|
|
|
|
```
|
|
MERGE (n :Student {name:"Jack",age:22})
|
|
ON CREATE SET n.nicknames=["Jacko"]
|
|
ON MATCH SET n.nicknames=["Jackie"];
|
|
```
|
|
|
|
#### Select
|
|
|
|
Match all nodes with label "Student", show name and first of the nickname(s)
|
|
|
|
```
|
|
MATCH (n :Student) RETURN n.name, n.nicknames[0];
|
|
```
|
|
|
|
```
|
|
MATCH (rog :Student {name: "Roger"}), (tim :Student {name: "Timothy"}) RETURN rog, tim
|
|
```
|
|
|
|
##### Where clause
|
|
|
|
Match all nodes with label "Student" and name "Tim"
|
|
|
|
```
|
|
MATCH (n :Student { name:"Roger" } ) RETURN n;
|
|
```
|
|
|
|
is the same as:
|
|
|
|
```
|
|
MATCH (n :Student ) WHERE n.name="Roger" RETURN n;
|
|
```
|
|
|
|
###### AND
|
|
|
|
```
|
|
MATCH (n :Student ) WHERE n.name="Roger" AND n.age=42 RETURN n;
|
|
```
|
|
|
|
###### OR
|
|
|
|
```
|
|
MATCH (n :Student ) WHERE n.name="Roger" OR n.age=21 RETURN n;
|
|
```
|
|
|
|
###### NOT
|
|
|
|
```
|
|
MATCH (n) WHERE n.name<>"Roger" AND n.name<>"Josh" RETURN n;
|
|
```
|
|
|
|
or
|
|
|
|
```
|
|
MATCH (n) WHERE NOT n.name="Roger" AND NOT n.name="Josh" RETURN n;
|
|
```
|
|
|
|
###### Smaller/Larger
|
|
|
|
```
|
|
MATCH (n) WHERE n.age>=21 RETURN n;
|
|
```
|
|
|
|
#### Update
|
|
|
|
##### Update Node Property
|
|
|
|
Student "Tim" name auf "Timothy" ändern.
|
|
|
|
```
|
|
MATCH (n :Student { name:"Tim" }) SET n.name="Timothy" RETURN n;
|
|
```
|
|
|
|
##### Update Label
|
|
|
|
Give the label with name "Roger" the labels "Student" and "Teacher".
|
|
|
|
```
|
|
MATCH (n {name:"Roger"}) SET n:Student, n:Teacher RETURN n;
|
|
```
|
|
|
|
#### Remove
|
|
|
|
Entfernen zweier Labels vom Node:
|
|
|
|
```
|
|
MATCH (n :Student {name:"Roger"}) REMOVE n:Teacher, n:Student RETURN n;
|
|
```
|
|
|
|
Entfernen der Property `address`:
|
|
|
|
```
|
|
MATCH (n :Student {name:"Roger"}) REMOVE n.address RETURN n;
|
|
```
|
|
|
|
#### Delete
|
|
|
|
Delete a node
|
|
|
|
```
|
|
MATCH (n :User) DELETE n RETURN n;
|
|
```
|
|
|
|
### Relations
|
|
|
|
```
|
|
(node1)-[:FRIEND]->(node2) --> Uni-Directional
|
|
(node1)<-[:FRIEND]-(node2) --> Uni-Directional
|
|
(node1)-[:FRIEND]-(node2) --> Bi-Directional
|
|
```
|
|
|
|
`[:FRIEND]` ist ein Type. Wie ein Label bei den Nodes. Aber im Gegensatz zu Labelnodes ist nur ein Type pro Relationship möglich.
|
|
|
|
#### Create
|
|
|
|
Create a Uni-Directional Relationship between Roger and Timothy called "Friend".
|
|
|
|
```
|
|
MATCH (rog :Student {name: "Roger"}), (tim :Student {name: "Timothy"})
|
|
CREATE (rog)-[:FRIEND]->(tim)
|
|
RETURN rog, tim
|
|
```
|
|
|
|
Hier noch mit einer Relation Property
|
|
|
|
```
|
|
MATCH (rog :Student {name: "Roger"}), (tim :Student {name: "Timothy"})
|
|
CREATE (rog)-[r :FRIEND {nickname:"Timmi"}]->(tim)
|
|
RETURN rog, r, tim
|
|
```
|
|
|
|
Um eine Bi-Directional Relation zu machen, muss einfach noch der umgekehrte Weg gemacht werden:
|
|
|
|
```
|
|
MATCH (rog :Student {name: "Roger"}), (tim :Student {name: "Timothy"})
|
|
CREATE (rog)<-[r :FRIEND {nickname:"Rocket"}]-(tim)
|
|
RETURN rog, r, tim
|
|
```
|
|
|
|
Bi-Directional auf einen Chlapf:
|
|
|
|
```
|
|
MATCH (rog :Student {name: "Roger"}), (jac :Student {name: "Jack"})
|
|
CREATE (rog)-[r1 :FRIEND {nickname:"Rocket"}]->(jac)<-[r2 :FRIEND {nickname:"jaccc"}]-(rog)
|
|
RETURN rog, r1, r2, jac
|
|
```
|
|
|
|
#### Select
|
|
|
|
Select Relationship between 2 nodes
|
|
|
|
```
|
|
MATCH (rog :Student {name:"Roger"})-[r]-(tim :Student {name:"Timothy"})
|
|
RETURN rog, r, tim
|
|
```
|
|
|
|
#### Update
|
|
|
|
Update Relationship Property
|
|
|
|
```
|
|
MATCH (:Student {name: "Roger"})<-[r:FRIEND]-(:Student {name: "Timothy"})
|
|
SET r.nickname = "Rog"
|
|
RETURN r
|
|
```
|
|
|
|
#### Delete
|
|
|
|
Löschen einer Relationship. Roger will nicht mehr Freund von Timothy sein.
|
|
|
|
```
|
|
MATCH (rog :Student {name:"Roger"})-[r:FRIEND]->(tim :Student {name:"Timothy"})
|
|
DELETE r
|
|
RETURN rog, r, tim
|
|
```
|
|
|
|
oder für alle Directions:
|
|
|
|
```
|
|
MATCH (rog :Student {name:"Roger"})-[r:FRIEND]-(tim :Student {name:"Timothy"})
|
|
DELETE r
|
|
RETURN rog, r, tim
|
|
```
|
|
|
|
### Node and Relation
|
|
|
|
#### Create
|
|
|
|
Create 2 nodes and relations
|
|
|
|
```
|
|
CREATE p = (da :Student {name:"Daisy", age:30})-[:FRIEND {nickname:"Annabella"}]->(a :Student {name:"Anna", age:31})-[:FRIEND {nickname:"Day"}]->(da)
|
|
RETURN p;
|
|
```
|
|
|
|
#### Merge
|
|
|
|
Used if you don't want to create new entries if it's alreedy there. Doing the following query multiple times will result only in one relationship, whereas `CREATE` would create new relationships each time.
|
|
|
|
Here, Roger and Timothy already exist:
|
|
|
|
```
|
|
MATCH (rog :Student {name: "Roger"}), (tim :Student {name: "Timothy"})
|
|
MERGE (rog)<-[r1 :CLASSMATE]-(tim)
|
|
MERGE (rog)-[r2 :CLASSMATE]->(tim)
|
|
RETURN rog, tim, type(r1), r1, type(r2), r2;
|
|
```
|
|
|
|
Here, Roger exists, and Dave is created if not existing.
|
|
|
|
```
|
|
MATCH (rog :Student {name: "Roger"})
|
|
MERGE (dav :Student {name: "Dave", age:25})
|
|
MERGE (rog)<-[r1 :CLASSMATE]-(dav)
|
|
MERGE (rog)-[r2 :CLASSMATE]->(dav)
|
|
RETURN rog, dav, type(r1), r1, type(r2), r2;
|
|
```
|
|
|
|
#### Create Unique
|
|
|
|
! Deprecated in Neo4j version 3.2
|
|
|
|
Assuming Roger and Dave alredy exists, and they are connected by relationship `CLASSMATE`.
|
|
`CREATE UNIQUE` Will create the relationship and the new node if it is not there (completely, relationship AND node). There is no relationship `FRIEND`, so it will create a new node `Dave` even though `Dave` already exists, but this time with the relationship `FRIEND`. So we have `Roger` and 2 times `Dave`, one with relation `CLASSMATE` and the other with relation `FRIEND`.
|
|
|
|
```
|
|
MATCH (rog :Student {name: 'Roger'})
|
|
CREATE UNIQUE (rog)-[r :FRIEND]->(dav :Student {name:"Dave", age:25})
|
|
RETURN rog, type(r), dav;
|
|
```
|