Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions modules/ROOT/pages/clauses/create.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,57 @@ Nodes created: 2 +
Properties set: 4
|===

[role=label--new-5.26]
[[dynamic-create]]
== CREATE nodes and relationships using dynamic node labels and relationship types
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really long title, is it possible to make it shorter?

CREATE using dynamic node labels and relationship types perhaps?


Node labels and relationship types can be referenced dynamically in parameters and variables when creating nodes and relationships.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we say they can be dynamically calculated from expressions? Because it isn't only parameters and variables that are allowed


.Syntax for creating nodes and relationships dynamically
[source, syntax]
----
CREATE (n:$(<expr>)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CREATE (n:$(<expr>)),
CREATE (n:$(<expr>))

CREATE ()-[r:$(<expr>)]->()
----

The expression must evaluate to a `STRING NOT NULL | LIST<STRING NOT NULL> NOT NULL` value.

.Parameters
[source, parameters]
----
{
"nodeLabels": ["Person", "Director"],
"relType": "DIRECTED",
"movies": ["Ladybird", "Little Women", "Barbie"]
}
----

.Create nodes and relationships using dynamic node labels and relationship types
[source, cypher]
----
CREATE (greta:$($nodeLabels) {name: 'Greta Gerwig'})
WITH greta
UNWIND $movies AS movieTitle
CREATE (greta)-[:$($relType)]->(m:Movie {title: movieTitle})
RETURN greta.name AS name, labels(greta) AS gretaLabels, collect(m.title) AS moviesDirected
----

.Result
[role="queryresult",options="footer",cols="3*<m"]
|===
| name | gretaLabels | moviesDirected

| "Greta Gerwig"
| ["Person, "Director"]
| ["Ladybird", "Little Women", "Barbie"]

3+d|Rows: 1 +
Nodes created: 4 +
Relationships created: 3 +
Properties set: 4 +
Labels added: 5
|===

[role=label--new-5.18]
[[insert-as-synonym-of-create]]
== `INSERT` as a synonym of `CREATE`
Expand Down
37 changes: 37 additions & 0 deletions modules/ROOT/pages/clauses/load-csv.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,43 @@ Added 4 nodes, Set 8 properties, Added 4 labels
|===
====

[role=label--new-5.26]
[[dynamic-columns]]
=== Import CSV files using dynamic columns

CSV columns can be referenced dynamically to map labels to nodes in the graph. This enables flexible data handling, allowing labels to be be populated from CSV column values without manually specifying each entry.

.bands-with-headers.csv
[source, csv, filename="artists-with-headers.csv"]
----
Id,Label,Name
1,Band,The Beatles
2,Band,The Rolling Stones
3,Band,Pink Floyd
4,Band,Led Zeppelin
----

.Query
[source, cypher, role=test-skip]
----
LOAD CSV WITH HEADERS FROM 'file:///bands-with-headers.csv' AS line
MERGE (n:$(line.Label) {name: line.Name})
RETURN n AS bandNodes
----

.Result
[role="queryresult",options="header,footer",cols="1*<m"]
|===
| bandNodes

| (:Band {name: 'The Beatles'})
| (:Band {name: 'The Rolling Stones'})
| (:Band {name: 'Pink Floyd'})
| (:Band {name: 'Led Zeppelin'})

1+d|Rows: 4 +
Added 4 nodes, Set 4 properties, Added 4 labels
|===

=== Import compressed CSV files

Expand Down
132 changes: 132 additions & 0 deletions modules/ROOT/pages/clauses/match.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -490,3 +490,135 @@ The above query uses the xref:functions/aggregating.adoc#functions-collect[`coll

For more information about how Cypher queries work, see xref:clauses/clause-composition.adoc[].

[role=label--new-5.26]
[[dynamic-match]]
== MATCH nodes and relationships using dynamic node labels and relationship types
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here:

MATCH using dynamic node labels and relationship types


Node labels and relationship types can be referenced dynamically in parameters and variables when matching nodes and relationships.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about expressions


.Syntax for matching node labels dynamically
[source, syntax]
----
MATCH (n:$(<expr>))
MATCH (n:$any(<expr>))
MATCH (n:$all(<expr>))
----

.Syntax for matching relationship types dynamically
[source, syntax]
----
MATCH ()-[r:$(<expr>))]->()
MATCH ()-[r:$any(<expr>)]->()
MATCH ()-[r:$all(<expr>))]->()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it be specified that all and not specifying one are the same meaning?

----

The expression must evaluate to a `STRING NOT NULL | LIST<STRING NOT NULL> NOT NULL` value.

.Match labels dynamically using the `all()` function
[source, cypher]
----
WITH "Movie" AS label
MATCH (movie:$all(label))
RETURN movie AS movieNodes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we are showcasing all explicitly then we should have more than one label and explain it is the conjunction

----

.Result
[role="queryresult",options="header,footer",cols="1*<m"]
|===
| movieNodes

| (:Movie {title: "Wall Street"})
| (:Movie {title: "The American President"})

1+d|Rows: 2
|===

[NOTE]
The xref:functions/predicate.adoc#functions-all[`all()`] function matches nodes that have all the specified labels.

If passing a `LIST<STRING>` to an `all()` function evaluating a relationship pattern using dynamic relationship types, the list cannot contain more than one element.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can, it just won't match on anything (emitting a warning is not the same as disallowed) :)

This is because a relationship can only have exactly one type.

.Attempting to match relationship patterns using more than one relationship type will not return any results
[source, cypher]
----
MATCH ()-[r:$all(["ACTED_IN", "DIRECTED"])]->()
RETURN r
----

.Warning
[source, warning]
----
Warning: The query contains a relationship type expression that cannot be satisfied.
----

.Match nodes dynamically using the `any()` function
[source, cypher]
----
MATCH (n:$any(["Movie", "Person"]))-[:ACTED_IN|DIRECTED]->(m:Movie)
RETURN labels(n) AS labels, n.name AS person, collect(m.title) AS movies
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe do a match without the relationship? then you don't have the non-dynamic part and the output can be just the nodes that are either movies or people

----

[NOTE]
The xref:functions/predicate.adoc#functions-any[`any()`] function matches nodes that have any of the specified labels.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds like the any in the match is the any() function, but it isn't. It's behaviour is modeled off of the any function, but it is not identical, so maybe clarify this part a little more


.Result
[role="queryresult",options="header,footer",cols="3*<m"]
|===
| labels | person | movies
| ["Person"] | Charlie Sheen | ["Wall Street"]
| ["Person"] | Martin Sheen | ["Wall Street", "The American President"]
| ["Person"] | Michael Douglas | ["Wall Street", "The American President"]
| ["Person"] | Oliver Stone | ["Wall Street"]
| ["Person"] | Rob Reiner | ["The American President"]

3+d|Rows: 5
|===


.Parameter
[source, parameters]
----
{
"label": "Movie"
}
----

.Match nodes dynamically using a parameter
[source, cypher]
----
MATCH (movie:$($label))
RETURN movie.title AS movieTitle
----

.Result
[role="queryresult",options="header,footer",cols="1*<m"]
|===
| movieTitle

| "Wall Street"
| "The American President"

1+d|Rows: 2
|===


.Match relationships dynamically using a variable
[source, cypher]
----
CALL db.relationshipTypes()
YIELD relationshipType
MATCH ()-[r:$(relationshipType)]-()
RETURN relationshipType, count(r) AS relationshipCount
----

.Result
[role="queryresult",options="header,footer",cols="2*<m"]
|===
| relationshipType | relationshipCount

| "ACTED_IN" | 5
| "DIRECTED" | 2

2+d|Rows: 2
|===
52 changes: 52 additions & 0 deletions modules/ROOT/pages/clauses/merge.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -683,3 +683,55 @@ RETURN person.name, person.bornIn, person.chauffeurName
| person.name | person.bornIn | person.chauffeurName
| "Keanu Reeves" | "Beirut" | "Eric Brown"
|===

[role=label--new-5.26]
[[dynamic-merge]]
== MERGE nodes and relationships using dynamic node labels and relationship types
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MERGE using dynamic node labels and relationship types


Node labels and relationship types can be referenced dynamically in parameters and variables when merging nodes and relationships.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same point about expressions


.Syntax for merging nodes and relationships dynamically
[source, syntax]
----
MERGE (n:$(<expr>)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
MERGE (n:$(<expr>)),
MERGE (n:$(<expr>))

MERGE ()-[r:$(<expr>)]->()
----

The expression must evaluate to a `STRING NOT NULL | LIST<STRING NOT NULL> NOT NULL` value.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to mention maybe that relationships can still only have one type, even if a list is supplied


.Parameters
[source, parameters]
----
{
"nodeLabels": ["Person", "Director"],
"relType": "DIRECTED",
"movies": ["Ladybird", "Little Women", "Barbie"]
}
----

.Merge nodes and relationships using dynamic node labels and relationship types
[source, cypher]
----
MERGE (greta:$($nodeLabels) {name: 'Greta Gerwig'})
WITH greta
UNWIND $movies AS movieTitle
MERGE (greta)-[:$($relType)]->(m:Movie {title: movieTitle})
RETURN greta.name AS name, labels(greta) AS gretaLabels, collect(m.title) AS moviesDirected
----

.Result
[role="queryresult",options="footer",cols="3*<m"]
|===
| name | gretaLabels | moviesDirected

| "Greta Gerwig"
| ["Person, "Director"]
| ["Ladybird", "Little Women", "Barbie"]

3+d|Rows: 1 +
Nodes created: 4 +
Relationships created: 3 +
Properties set: 4 +
Labels added: 5
|===

12 changes: 6 additions & 6 deletions modules/ROOT/pages/clauses/remove.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ Properties set: 1
Instead, using xref::clauses/set.adoc#set-remove-properties-using-empty-map[`SET` with `=` and an empty map as the right operand] will clear all properties from the node or relationship.

[role=label--new-5.24]
[[remove-remove-a-property-dynamically]]
== Dynamically removing a property
[[dynamic-remove-property]]
== Dynamically remove a property

`REMOVE` can be used to remove a property on a node or relationship even when the property key name is not statically known.

Expand All @@ -82,7 +82,6 @@ REMOVE n[key]
The dynamically calculated key must evaluate to a `STRING` value.
This query creates a copy of every property on the nodes:


.Query
[source, cypher, indent=0]
----
Expand Down Expand Up @@ -131,18 +130,19 @@ Labels removed: 1
|===

[role=label--new-5.24]
[[remove-remove-a-label-dynamically-from-a-node]]
== Dynamically removing a label
[[dynamic-remove-node-label]]
== Dynamically remove a node label

`REMOVE` can be used to remove a label on a node even when the label is not statically known.


[source, syntax]
----
MATCH (n)
REMOVE n:$(expr)
----

The expression must evaluate to a `STRING NOT NULL | LIST<STRING NOT NULL> NOT NULL` value.

.Query
[source, cypher, indent=0]
----
Expand Down
8 changes: 4 additions & 4 deletions modules/ROOT/pages/clauses/set.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ Properties set: 1


[role=label--new-5.24]
[[set-dynamically-a-property]]
== Dynamically setting or updating a property
[[dynamic-set-property]]
== Dynamically set or update a property

`SET` can be used to set or update a property on a node or relationship even when the property key name is not statically known.

Expand Down Expand Up @@ -541,8 +541,8 @@ Labels added: 1
|===

[role=label--new-5.24]
[[set-set-a-dynamic-label-on-a-node]]
== Dynamically setting a label
[[dynamic-set-node-label]]
== Dynamically set a node label

`SET` can be used to set a label on a node even when the label is not statically known.

Expand Down
Loading