Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NOID] Fixes #4263: Adds docs for apoc triggers helper functions (#4311) #4325

Merged
merged 2 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

`apoc.custom.list()` - provide a list of custom procedures/function registered
¦label:procedure[]
¦label:apoc-extended[]
¦label:apoc-full[]
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

`apoc.custom.list()` - provide a list of custom procedures/function registered
¦label:procedure[]
¦label:apoc-extended[]
¦label:apoc-full[]
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

`apoc.custom.list()` - provide a list of custom procedures/function registered
¦label:procedure[]
¦label:apoc-extended[]
¦label:apoc-full[]
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

`apoc.custom.list()` - provide a list of custom procedures/function registered
¦label:procedure[]
¦label:apoc-extended[]
¦label:apoc-full[]
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

`apoc.custom.list()` - provide a list of custom procedures/function registered
¦label:procedure[]
¦label:apoc-extended[]
¦label:apoc-full[]
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

`apoc.custom.list()` - provide a list of custom procedures/function registered
¦label:procedure[]
¦label:apoc-extended[]
¦label:apoc-full[]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
¦xref::overview/apoc.trigger/apoc.trigger.nodesByLabel.adoc[apoc.trigger.nodesByLabel icon:book[]] +

``
`apoc.trigger.nodesByLabel(labelEntries, label)` - function to filter labelEntries by label, to be used within a trigger kernelTransaction with `$assignedLabels`, `$removedLabels`, `$assigned/removedNodeProperties`.
¦label:function[]
¦label:apoc-full[]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
¦xref::overview/apoc.trigger/apoc.trigger.propertiesByKey.adoc[apoc.trigger.propertiesByKey icon:book[]] +

``
`apoc.trigger.propertiesByKey(propertyEntries, key)` - function to filter propertyEntries by property-key, to be used within a trigger kernelTransaction with `$assignedNode/RelationshipProperties` and `$removedNode/RelationshipProperties`. Returns [`old`,`new`,`key`,`node`,`relationship`].
¦label:function[]
¦label:apoc-full[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
¦signature
¦apoc.trigger.nodesByLabel(labelEntries :: ANY?, label :: STRING?) :: (LIST? OF ANY?)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
¦xref::overview/apoc.trigger/apoc.trigger.toNode.adoc[apoc.trigger.toNode icon:book[]] +

`apoc.trigger.toNode(node, removedLabels, removedNodeProperties)` - function to rebuild a node as a virtual one, to be used in triggers with a not 'afterAsync' phase.
¦label:function[]
¦label:apoc-full[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
¦type¦qualified name¦signature¦description
¦function¦apoc.trigger.nodesByLabel¦apoc.trigger.nodesByLabel(labelEntries :: ANY?, label :: STRING?) :: (LIST? OF ANY?)¦
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
¦signature
¦apoc.trigger.nodesByLabel(labelEntries :: ANY?, label :: STRING?) :: (LIST? OF ANY?)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
¦xref::overview/apoc.trigger/apoc.trigger.toRelationship.adoc[apoc.trigger.toRelationship icon:book[]] +

`apoc.trigger.toRelationship(rel, removedRelationshipProperties)` - function to rebuild a relationship as a virtual one, to be used in triggers with a not 'afterAsync' phase.
¦label:function[]
¦label:apoc-full[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
¦type¦qualified name¦signature¦description
¦function¦apoc.trigger.nodesByLabel¦apoc.trigger.nodesByLabel(labelEntries :: ANY?, label :: STRING?) :: (LIST? OF ANY?)¦
1 change: 1 addition & 0 deletions docs/asciidoc/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ include::partial$generated-documentation/nav.adoc[]
* xref:background-operations/index.adoc[]
** xref::background-operations/periodic-background.adoc[]
** xref::background-operations/triggers.adoc[]
** xref::background-operations/apoc-load-directory-async.adoc[]

* xref:database-introspection/index.adoc[]
** xref::database-introspection/meta.adoc[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ include::example$generated-documentation/apoc.trigger.stop.adoc[]
include::example$generated-documentation/apoc.trigger.start.adoc[]
include::example$generated-documentation/apoc.trigger.show.adoc[]
include::example$generated-documentation/apoc.trigger.list.adoc[]

|===


Expand Down Expand Up @@ -53,12 +54,13 @@ Otherwise, it has the value `-1`.
You can use these helper functions to extract nodes or relationships by label/relationship-type or updated property key.

.Helper Functions
[cols="5m,5"]
[separator=¦,opts=header,cols="5,1m,1m"]
|===
| apoc.trigger.nodesByLabel($assignedLabels/$assignedNodeProperties,'Label') | function to filter entries by label, to be used within a trigger statement with `$assignedLabels` and `$removedLabels`
| apoc.trigger.propertiesByKey($assignedNodeProperties,'key') | function to filter propertyEntries by property-key, to be used within a trigger statement with $assignedNode/RelationshipProperties and $removedNode/RelationshipProperties. Returns [{old,[new],key,node,relationship}]
| apoc.trigger.toNode(node, $removedLabels, $removedNodeProperties) | function to rebuild a node as a virtual, to be used in triggers with a not 'afterAsync' phase
| apoc.trigger.toRelationship(rel, $removedRelationshipProperties) | function to rebuild a relationship as a virtual, to be used in triggers with a not 'afterAsync' phase
¦Qualified Name¦Type¦Release
include::example$generated-documentation/apoc.trigger.nodesByLabel.adoc[]
include::example$generated-documentation/apoc.trigger.propertiesByKey.adoc[]
include::example$generated-documentation/apoc.trigger.toNode.adoc[]
include::example$generated-documentation/apoc.trigger.toRelationship.adoc[]
|===

The 3rd parameter of the `apoc.trigger.install()` is a map `{phase: PHASE}`, where `PHASE` is a string which can have one of the following values:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
= apoc.agg.multiStats
:description: This section contains reference documentation for the apoc.agg.multiStats function.

label:function[] label:apoc-extended[]
label:function[] label:apoc-full[]

[.emphasis]
apoc.agg.multiStats(nodeOrRel, keys) - Return a multi-dimensional aggregation
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
= apoc.convert.fromYaml
:description: This section contains reference documentation for the apoc.convert.fromYaml function.

label:function[] label:apoc-extended[]
label:function[] label:apoc-full[]

[.emphasis]
apoc.convert.fromYaml(value, $config) - Deserializes the YAML string to Neo4j value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
= apoc.custom.dropAll
:description: This section contains reference documentation for the apoc.custom.dropAll procedure.

label:procedure[] label:apoc-extended[]
label:procedure[] label:apoc-full[]

[.emphasis]
Eventually drops all previously added custom procedures/functions and returns info
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
= apoc.custom.dropFunction
:description: This section contains reference documentation for the apoc.custom.dropFunction procedure.

label:procedure[] label:apoc-extended[]
label:procedure[] label:apoc-full[]

[.emphasis]
Eventually drops the targeted custom function
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
= apoc.custom.dropProcedure
:description: This section contains reference documentation for the apoc.custom.dropProcedure procedure.

label:procedure[] label:apoc-extended[]
label:procedure[] label:apoc-full[]

[.emphasis]
Eventually drops the targeted custom procedure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
= apoc.custom.installFunction
:description: This section contains reference documentation for the apoc.custom.installFunction procedure.

label:procedure[] label:apoc-extended[]
label:procedure[] label:apoc-full[]

[.emphasis]
Eventually registers a custom cypher function
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
= apoc.custom.installProcedure
:description: This section contains reference documentation for the apoc.custom.installProcedure procedure.

label:procedure[] label:apoc-extended[]
label:procedure[] label:apoc-full[]

[.emphasis]
Eventually registers a custom cypher procedure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
= apoc.custom.show
:description: This section contains reference documentation for the apoc.custom.show procedure.

label:procedure[] label:apoc-extended[]
label:procedure[] label:apoc-full[]

[.emphasis]
Provides a list of custom procedures/function registered
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
= apoc.import.arrow
:description: This section contains reference documentation for the apoc.import.arrow procedure.

label:procedure[] label:apoc-extended[]
label:procedure[] label:apoc-full[]

[.emphasis]
apoc.import.arrow(input, $config) - Imports arrow from the provided arrow file or byte array
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

= apoc.trigger.toNode
:description: This section contains reference documentation for the apoc.trigger.toNode function.

label:function[] label:apoc-full[]

== Signature

[source]
----
apoc.trigger.toNode(node :: NODE, removedLabels :: MAP, removedNodeProperties :: MAP) :: RELATIONSHIPH
----

== Input parameters
[.procedures, opts=header]
|===
| Name | Type | Default
|node|NODE|null
|removedLabels|MAP|null
|removedNodeProperties|MAP|null
|===

[[usage-apoc.trigger.nodesByLabel]]
== Usage Examples
include::partial$usage/apoc.trigger.toNode.adoc[]

xref::background-operations/triggers.adoc[More documentation of apoc.trigger.toNode,role=more information]

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

= apoc.trigger.toRelationship
:description: This section contains reference documentation for the apoc.trigger.toRelationship function.

label:function[] label:apoc-full[]

== Signature

[source]
----
apoc.trigger.toRelationship(rel :: RELATIONSHIP, removedRelationshipProperties :: MAP) :: RELATIONSHIP
----

== Input parameters
[.procedures, opts=header]
|===
| Name | Type | Default
|rel|RELATIONSHIP|null
|removedRelationshipProperties|MAP|null
|===

[[usage-apoc.trigger.nodesByLabel]]
== Usage Examples
include::partial$usage/apoc.trigger.toRelationship.adoc[]

xref::background-operations/triggers.adoc[More documentation of apoc.trigger.toNode,role=more information]

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
= apoc.util.hashCode
:description: This section contains reference documentation for the apoc.util.hashCode function.

label:function[] label:apoc-extended[]
label:function[] label:apoc-full[]

[.emphasis]
apoc.util.hashCode(value) - Returns the java.lang.Object#hashCode() of the value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ create constraint on (p:Person)
assert p.id is unique;
----

This function is used inside a xref::overview/apoc.trigger/apoc.trigger.add.adoc[] Cypher statement.
This function is used inside a xref::overview/apoc.trigger/apoc.trigger.install.adoc[] Cypher statement.

We can use it to conditionally run Cypher statements when labels are added or removed or when properties are added or removed.
For example, we add an `id` property to all `Person` nodes that is the lower case value of the `name` property of that node, by defining the following trigger:

[source,cypher]
----
CALL apoc.trigger.add(
CALL apoc.trigger.install(
'neo4j',
'lowercase',
'UNWIND apoc.trigger.nodesByLabel($assignedLabels,"Person") AS n
SET n.id = toLower(n.name)',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
This function is used inside a xref::overview/apoc.trigger/apoc.trigger.add.adoc[] Cypher statement.
This function is intended to be used within an xref::overview/apoc.trigger/apoc.trigger.install.adoc[] Cypher statement.

We can use it to conditionally run Cypher statements when properties are added or removed.
For example, we can connect nodes with a `genre` property to a `Genre` node, with the following trigger:

[source,cypher]
----
CALL apoc.trigger.add(
CALL apoc.trigger.install(
'neo4j',
'triggerTest',
'UNWIND apoc.trigger.propertiesByKey($assignedNodeProperties, "genre") as prop
WITH prop.node as n
Expand Down
46 changes: 46 additions & 0 deletions docs/asciidoc/modules/ROOT/partials/usage/apoc.trigger.toNode.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
This function is intended to be used within an xref::overview/apoc.trigger/apoc.trigger.install.adoc[] Cypher statement.

If we want to create a 'before' or 'after' trigger query using `$deletedNodes`, and retrieve entity information such as labels and/or properties, we cannot use the classic Cypher functions labels() and properties().
Instead, we have to leverage virtual nodes through the function `apoc.trigger.toNode(node, $removedLabels, $removedNodeProperties)`.

For example, to create a new `Report` node with a list of deleted node IDs and all the labels retrieved for each deleted node, we can execute:
[source,cypher]
----
CALL apoc.trigger.install(
'neo4j', 'myTrigger',
"UNWIND $deletedNodes as deletedNode
WITH apoc.trigger.toNode(deletedNode, $removedLabels, $removedNodeProperties) AS deletedNode
CALL apoc.merge.node(
['Report'],
{labels: apoc.node.labels(deletedNode)},
{created: datetime()},
{updated: datetime()}
) YIELD node AS report
WITH report, deletedNode
SET report.deletedIds = coalesce(report.deletedIds, [])+[id(deletedNode)]" ,
{phase:'before'}
);
----

Now, let's create and delete a `Movie` node:

[source,cypher]
----
CREATE (:Movie {title: "The White Tiger"});
MATCH (movie:Movie {title: "The White Tiger"}) DELETE movie;
----

Finally, let's check the `Report` node:

[source,cypher]
----
MATCH (report:Report {labels: ['Movie']})
RETURN report;
----

.Results
[opts="header"]
|===
| report
| (:Report {"created": "2024-12-12T08:33:27.188000000Z", "deletedIds": [12], "labels": ["Movie"]})
|===
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
This function is intended to be used within an xref::overview/apoc.trigger/apoc.trigger.install.adoc[] Cypher statement.

If we want to create a 'before' or 'after' trigger query using `$deletedRelationships`, and retrieve entity information such as the type and/or properties, we cannot use the classic Cypher functions type() and properties().
Instead, we have to leverage virtual relationships through the function `apoc.trigger.toRelationship(rel, $removedRelationshipProperties)`.

For example, to create a new `Report` node with a list of deleted relationship IDs and the type retrieved for each deleted relationship, we can execute:
[source,cypher]
----
CALL apoc.trigger.install(
'neo4j', 'myTrigger',
"UNWIND $deletedRelationships as deletedRel
WITH apoc.trigger.toRelationship(deletedRel, $removedRelationshipProperties) AS deletedRel
CALL apoc.merge.node(
['Report'],
{type: apoc.rel.type(deletedRel)},
{created: datetime()},
{updated: datetime()}
) YIELD node AS report
WITH report, deletedRel
SET report.deletedIds = coalesce(report.deletedIds, [])+[id(deletedRel)]" ,
{phase:'before'}
);
----

Now, let's create and delete a `IN_GENRE` relationship between a `Movie` node and a `Genre` node:

[source,cypher]
----
MERGE (movie:Movie {title: "The White Tiger"})
MERGE (genre:Genre {name: "Triller"})
MERGE (movie)-[IN_GENRE]->(genre);
MATCH (movie:Movie {title: "The White Tiger"})-[r:IN_GENRE]->(genre:Genre {name: "Triller"}) DELETE r;
----

Finally, let's check the `Report` node:

[source,cypher]
----
MATCH (report:Report {labels: ['IN_GENRE']})
RETURN report;
----

.Results
[opts="header"]
|===
| report
| (:Report {"created": "2024-12-12T08:33:27.188000000Z", "deletedIds": [12], "type": "IN_GENRE"})
|===
Loading