Skip to content

Commit

Permalink
Restructure the main part of create.adoc (#670)
Browse files Browse the repository at this point in the history
  • Loading branch information
arnefischereit authored Sep 8, 2023
1 parent d009321 commit e42f85a
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 187 deletions.
247 changes: 61 additions & 186 deletions modules/ROOT/pages/clauses/create.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,247 +3,122 @@
[[query-create]]
= CREATE

[abstract]
--
The `CREATE` clause is used to create nodes and relationships.
--
== Introduction

The `CREATE` clause allows you to create nodes and relationships.
To define these entities, `CREATE` uses a syntax similar to that of xref::clauses/match.adoc[`MATCH`].
However, while xref::patterns/index.adoc[patterns] only need to evaluate to either true or false, the syntax for `CREATE` needs to specify exactly what nodes and relationships to create.

[[create-nodes]]
== Create nodes
== Syntax for nodes

[[create-create-single-node]]
=== Create single node

Creating a single node is done by issuing the following query:

.Query
[source, cypher, indent=0]
----
CREATE (n)
----

.Result
[role="queryresult",options="footer",cols="1*<m"]
|===
1+|(empty result)
1+d|Rows: 0 +
Nodes created: 1
|===


[[create-create-multiple-nodes]]
=== Create multiple nodes

Creating multiple nodes is done by separating them with a comma.
The `CREATE` clause allows you to create one or more nodes.
Each node can be assigned labels and properties.
You can bind each node to a variable that you can refer to later in the query.
Multiple labels are separated by colons.

.Query
[source, cypher, indent=0]
----
CREATE (n), (m)
CREATE (charlie:Person:Actor {name: 'Charlie Sheen'}), (oliver:Person:Director {name: 'Oliver Stone'})
----

.Result
[role="queryresult",options="footer",cols="1*<m"]
|===
1+|(empty result)
1+d|Rows: 0 +
Nodes created: 2
|===
Creates two nodes, bound to the variables `charlie` and `oliver`, each with a `Person` label and a `name` property.
The node representing Charlie Sheen also has the label `Actor` while the node representing Oliver Stone is assigned the label `Director`.

[[create-relationships]]
== Syntax for relationships

[[create-create-a-node-with-a-label]]
=== Create a node with a label

To add a label when creating a node, use the syntax below:
Relationships can also be created using the `CREATE` clause.
Unlike nodes, relationships always need exactly one relationship type and a direction.
Similar to nodes, relationships can be assigned properties and relationship types and be bound to variables.

.Query
[source, cypher, indent=0]
----
CREATE (n:Person)
CREATE (charlie:Person:Actor {name: 'Charlie Sheen'})-[:ACTED_IN {role: 'Bud Fox'}]->(wallStreet:Movie {title: 'Wall Street'})<-[:DIRECTED]-(oliver:Person:Director {name: 'Oliver Stone'})
----

.Result
[role="queryresult",options="footer",cols="1*<m"]
|===
1+|(empty result)
1+d|Rows: 0 +
Nodes created: 1 +
Labels added: 1
|===


[[create-create-a-node-with-multiple-labels]]
=== Create a node with multiple labels
This query creates the `Person` nodes for Charlie Sheen and Oliver Stone and the `Movie` node for Wall Street.
It also created the relationships of the types `ACTED_IN` and `DIRECTED` between them.

To add labels when creating a node, use the syntax below.
In this case, we add two labels.
[[reusing-variables]]
== Reusing variables
The previous example created a path between the specified nodes.
Note, that these newly created nodes and relationships are not connected to what was previously in the graph.
To connect them to already existing data, bind the desired nodes and relationships to variables.
These variables can then be passed along to subsequent clauses in a query that target pre-existing elements in the graph.

.Query
[source, cypher, indent=0]
----
CREATE (n:Person:Swedish)
MATCH (charlie:Person {name: 'Charlie Sheen'}), (oliver:Person {name: 'Oliver Stone'})
CREATE (charlie)-[:ACTED_IN {role: 'Bud Fox'}]->(wallStreet:Movie {title: 'Wall Street'})<-[:DIRECTED]-(oliver)
----

.Result
[role="queryresult",options="footer",cols="1*<m"]
|===
1+|(empty result)
1+d|Rows: 0 +
Nodes created: 1 +
Labels added: 2
|===

In this example, the `MATCH` clause finds the nodes Charlie Sheen and Oliver Stone and binds them to the `charlie` and `oliver` variables respectively.
These variables are then passed along to the subsequent `CREATE` clause, which creates new relationships from the bound nodes.

[[create-create-node-and-add-labels-and-properties]]
=== Create node and add labels and properties

When creating a new node with labels, you can add properties at the same time.
You can also reuse variables from the same `CREATE`, both in the same or a later clause.
This way, you can, for example, define constructs that are more complex than just a linear path.

.Query
[source, cypher, indent=0]
----
CREATE (n:Person {name: 'Andy', title: 'Developer'})
CREATE p = (charlie:Person:Actor {name: 'Charlie Sheen'})-[:ACTED_IN {role: 'Bud Fox'}]->(wallStreet:Movie {title: 'Wall Street'})<-[:DIRECTED]-(oliver:Person:Director {name: 'Oliver Stone'}), (wallStreet)<-[:ACTED_IN {role: 'Gordon Gekko'}]-(michael:Person:Actor {name: 'Michael Douglas'})
RETURN length(p)
----

.Result
[role="queryresult",options="footer",cols="1*<m"]
|===
1+|(empty result)
1+d|Rows: 0 +
Nodes created: 1 +
Properties set: 2 +
Labels added: 1
|===

Creates all three nodes for Charlie Sheen, Oliver Stone and Michael Douglas and connects them all to the node representing the Wall Street movie.
It then returns the length of the path from Charlie Sheen to Oliver Stone.

[[create-return-created-node]]
=== Return created node

Creating a single node is done by issuing the following query:
Note that when repeating a node's variable, you may not add labels or properties to the repetition.

.Query
[source, cypher, indent=0]
[source, cypher, role=test-fail]
----
CREATE (a {name: 'Andy'})
RETURN a.name
MATCH (charlie:Person {name: 'Charlie Sheen'})
CREATE (charlie:Actor)
----

The name of the newly-created node is returned.

.Result
[role="queryresult",options="header,footer",cols="1*<m"]
|===
| +a.name+
| +"Andy"+
1+d|Rows: 1 +
Nodes created: 1 +
Properties set: 1
|===


[[create-relationships]]
== Create relationships

[[create-create-a-relationship-between-two-nodes]]
=== Create a relationship between two nodes
This query will fail because the variable `charlie` has already been bound to a pre-existing node, and therefore it cannot be reused to create a new node.
If you intend to add a label, use the xref:clauses/set.adoc#set-set-a-label-on-a-node[`SET` clause] instead.

To create a relationship between two nodes, we first get the two nodes.
Once the nodes are loaded, we simply create a relationship between them.
[[reusing-variables-properties]]
== Reusing variables in properties
The value that can be assigned to a node's or a relationship's property can be defined by an xref::syntax/expressions.adoc[expression].

////
[source, cypher, role=test-setup]
----
CREATE
(a:Person {name: 'A'}),
(b:Person {name: 'B'})
----
////

.Query
[source, cypher]
.Parameters
[source,javascript, role=test-setup]
----
MATCH
(a:Person),
(b:Person)
WHERE a.name = 'A' AND b.name = 'B'
CREATE (a)-[r:RELTYPE]->(b)
RETURN type(r)
{
"age": 23
}
----

The created relationship is returned by the query.

.Result
[role="queryresult",options="header,footer",cols="1*<m"]
|===
| +type(r)+
| +"RELTYPE"+
1+d|Rows: 1 +
Relationships created: 1
|===


[[create-create-a-relationship-and-set-properties]]
=== Create a relationship and set properties

Setting properties on relationships is done in a similar manner to how it's done when creating nodes.
Note that the values can be any expression.

////
CREATE
(a:Person {name: 'A'}),
(b:Person {name: 'B'})
////

.Query
[source, cypher]
[source, cypher, indent=0]
----
MATCH
(a:Person),
(b:Person)
WHERE a.name = 'A' AND b.name = 'B'
CREATE (a)-[r:RELTYPE {name: a.name + '<->' + b.name}]->(b)
RETURN type(r), r.name
MATCH (person:Person)
WHERE person.name IS NOT NULL
CREATE (anotherPerson:Person {name: person.name, age: $age})
----

The type and name of the newly-created relationship is returned by the example query.

.Result
[role="queryresult",options="header,footer",cols="2*<m"]
|===
| +type(r)+ | +r.name+
| +"RELTYPE"+ | +"A<->B"+
2+d|Rows: 1 +
Relationships created: 1 +
Properties set: 1
|===

This example created a `Person` node with the same name as another person and the age from a xref:syntax/parameters.adoc[parameter] called `age`.

[[create-create-a-full-path]]
== Create a full path

When you use `CREATE` and a pattern, all parts of the pattern that are not already in scope at this time will be created.
Such an expression may not contain a reference to a variable that is defined in the same `CREATE` statement.
This is to ensure that the value of a property is always clear.

.Query
[source, cypher]
[source, cypher, role=test-fail]
----
CREATE p = (:Person {name:'Andy'})-[:WORKS_AT]->(:Company {name: 'Neo4j'})<-[:WORKS_AT]-(:Person {name: 'Michael'})
RETURN p
CREATE (charlie {score: oliver.score + 1}), (oliver {score: charlie.score + 1})
----

This query creates three nodes and two relationships in one go, assigns it to a path variable, and returns it.

.Result
[role="queryresult",options="header,footer",cols="1*<m"]
|===
| +p+
| (:Person {name: "Andy"})-[:WORKS_AT]->(:Company {name: "Neo4j"})<-[:WORKS_AT]-(:Person {name: "Michael"})
1+d|Rows: 1 +
Nodes created: 3 +
Relationships created: 2 +
Properties set: 2
|===

This query tries to create nodes such that Charlie's score is higher than Oliver's and vice versa, which is a contradiction.
The query therefore fails.

[[use-parameters-with-create]]
== Use parameters with `CREATE`
Expand Down
2 changes: 1 addition & 1 deletion modules/ROOT/pages/clauses/set.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ CREATE
----
////

xref::clauses/set.adoc#set-remove-properties-using-empty-map[In contrast to the property replacement operator `=`], providing an empty map as the right operand to `+=` will not remove any existing properties from a node or relationship.
xref:clauses/set.adoc#set-remove-properties-using-empty-map[In contrast to the property replacement operator `=`], providing an empty map as the right operand to `+=` will not remove any existing properties from a node or relationship.
In line with the semantics detailed above, passing in an empty map with `+=` will have no effect:

.Query
Expand Down

0 comments on commit e42f85a

Please sign in to comment.