Skip to main content
Version: Next version 🚧

# Triggers

Database triggers are an integral part of most database systems. A trigger is a procedural code that is automatically executed in response to specific events. Events are related to some change in data, such as created, updated and deleted data records. The trigger is often used for maintaining the integrity of the information in the database. For example, in a graph database, when a new property is added to the Employee node, a new Tax, Vacation, and Salary node should be created, along with the relationships between them. Triggers can also be used to log historical data, for example, to keep track of employees' previous salaries.

## Introduction​

Memgraph supports running openCypher clauses after a certain event happens during database transaction execution, i.e. triggers.

You can create, delete and print triggers. All the triggers are persisted on the disk, so no information is lost on database reruns.

## Creating a trigger​

To create a new trigger, a query of the following format should be used:

CREATE TRIGGER trigger_name ( ON ( () | --> ) CREATE | UPDATE | DELETE )( BEFORE | AFTER ) COMMITEXECUTE openCypherStatements

As you can see from the format, you can choose on what object event needs to happen , on () node or --> relationship. After that you can define on what type of event you what to execute the trigger CREATE, UPDATE or DELETE. After the EXECUTE is series of Cypher clauses you want to execute.

An example of a trigger would be:

CREATE TRIGGER exampleTriggerON UPDATE AFTER COMMIT EXECUTEUNWIND updatedObjects AS updatedObjectWITH CASE        WHEN updatedObject.vertex IS NOT null THEN updatedObject.vertex        WHEN updatedObject.edge IS NOT null THEN updatedObject.edge    END AS objectSET object.updated_at = timestamp();

The query may seem complex, so let's break it down:

• CREATE TRIGGER exampleTrigger: This statement creates the trigger. Here the part exampleTrigger is the name of the trigger and it must be unique.
• ON UPDATE AFTER COMMIT EXECUTE: This statement specifies what kind of event should activate the execution of trigger. This one will be triggered for every update operation and the query below will be executed after the update event has been committed.
• UNWIND updatedObjects AS updatedObject: If multiple objects were updated, unwind the list and go over each one.
• WITH CASE...: The CASE expression checks what type of object was updated, a node (vertex) or a relationship (edge).
• SET object.updated_at = timestamp();: Add an updated_at property to the object indicating when the action happened.

### Trigger name​

Each created trigger must have a globally unique name. This implies that you can't have a pair of triggers with the same name, even if they apply to different events.

### Event type​

Optionally, users can define on which event a trigger should execute its statements. The event type is defined using the following part:

ON ( () | --> ) CREATE | UPDATE | DELETE

There are three main event types:

• CREATE
• UPDATE
• DELETE

For each event type, users can specify whether to execute the trigger statements only on the events that happened on a vertex, or on an edge. Vertices are denoted with (), and edges with -->.

Few examples would be:

• ON CREATE - trigger the statements only if an object (vertex and/or edge) was created during the transaction execution.
• ON () UPDATE - trigger the statements only if a vertex was updated (e.g. property was set on it) during the transaction execution.
• ON --> DELETE - trigger the statements only if an edge was deleted during the transaction execution.

Each event comes with certain information that can be used in the openCypher statements the trigger executes. The information is contained in the form of predefined variables.

If no event type is specified, the trigger executes its statements every time, and all the predefined variables can be used.

### Statement execution phase​

A trigger can execute its statements at a specified phase, before or after committing the transaction that triggered it. If the BEFORE COMMIT option is used, the trigger will execute its statements as part of that transaction before it's committed. If the AFTER COMMIT option is used, the trigger will execute its statements asynchronously after that transaction is committed.

### Execute statements​

A trigger can execute any valid openCypher query. No specific constraints are imposed on the queries. The only way trigger queries (i.e. statements) differ from standard queries is that a trigger query may use predefined variables, which are based on the event type specified for the trigger.

### Predefined variables​

Statements that a trigger executes can contain certain predefined variables which contain information about the event that triggered it. Values of predefined variables are determined by database transactions, that is, by all the creations, updates or deletes that are part of a single transaction.

Based on the event type, the following predefined variables are available:

Event typePredefined variables
ON CREATEcreatedVertices, createdEdges, createdObjects
ON () CREATEcreatedVertices
ON --> CREATEcreatedEdges
ON UPDATEsetVertexProperties, setEdgeProperties, removedVertexProperties, removedEdgeProperties, setVertexLabels, removedVertexLabels, updatedVertices, updatedEdges, updatedObjects
ON () UPDATEsetVertexProperties, removedVertexProperties, setVertexLabels, removedVertexLabels, updatedVertices
ON --> UPDATEsetEdgeProperties, removedEdgeProperties, updatedEdges
ON DELETEdeletedVertices, deletedEdges, deletedObjects
ON () DELETEdeletedVertices
ON --> DELETEdeletedEdges
no event type specifiedAll predefined variables can be used

#### createdVertices​

List of all created vertices.

#### createdEdges​

List of all created edges

#### createdObjects​

List of all created objects where each element is a map. If the element contains a created vertex, it will be in the following format

{  "event_type": "created_vertex",  "vertex": created_vertex_object}

If the element contains a created edge, it will be in the following format

{  "event_type": "created_edge",  "edge": created_edge_object}

#### deletedVertices​

List of all deleted vertices.

#### deletedEdges​

List of all deleted edges

#### deletedObjects​

List of all deleted objects where each element is a map. If the element contains a deleted vertex, it will be in the following format

{  "event_type": "deleted_vertex",  "vertex": deleted_vertex_object}

If the element contains a deleted edge, it will be in the following format

{  "event_type": "deleted_edge",  "edge": deleted_edge_object}

#### General notes about the predefined variables for updates​

Setting an element to NULL is counted as a removal. The changes are looked at on the transaction level only. That means if the value under a property on the same object was changed multiple times, only one update will be generated. The same applies for the labels on the vertex.

#### setVertexProperties​

List of all set vertex properties. Each element is in the following format:

{  "vertex": updated_vertex_object,  "key": property_that_was_updated,  "old": old_value_of_that_property,  "new": new_value_of_that_property}

#### setEdgeProperties​

List of all set edge properties. Each element is in the following format:

{  "edge": updated_vertex_object,  "key": property_that_was_updated,  "old": old_value_of_that_property,  "new": new_value_of_that_property}

#### removedVertexProperties​

List of all removed vertex properties. Each element is in the following format:

{  "vertex": updated_vertex_object,  "key": property_that_was_updated,  "old": old_value_of_that_property}

#### removedEdgeProperties​

List of all removed edge properties. Each element is in the following format:

{  "vertex": updated_vertex_object,  "key": property_that_was_updated,  "old": old_value_of_that_property}

#### setVertexLabels​

List of all set vertex labels. Each element is in the following format:

{  "label": label,  "vertices": list_of_updated_vertices}

#### removedVertexLabels​

List of all removed vertex labels. Each element is in the following format:

{  "label": label,  "vertices": list_of_updated_vertices}

#### updatedVertices​

List of updates consisting of set and removed properties, and set and removed labels on vertices.

#### updatedEdges​

List of updates consisting of set and removed properties on edges.

#### updatedObjects​

List of updates consisting of set and removed properties on edges and vertices, and set and removed labels on vertices.

#### Elements of the predefined variables for update​

Each element has a similar format as the previously defined elements.

If the element contains information about a set vertex property, it's in the following format:

{  "event_type": "set_vertex_property",  "vertex": updated_vertex_object,  "key": property_that_was_updated,  "old": old_value_of_that_property,  "new": new_value_of_that_property}

If the element contains information about a removed vertex property, it's in the following format:

{  "event_type": "removed_vertex_property",  "vertex": updated_vertex_object,  "key": property_that_was_updated,  "old": old_value_of_that_property}

If the element contains information about a set edge property, it's in the following format:

{  "event_type": "set_edge_property",  "edge": updated_edge_object,  "key": property_that_was_updated,  "old": old_value_of_that_property,  "new": new_value_of_that_property}

If the element contains information about a removed edge property, it's in the following format:

{  "event_type": "removed_edge_property",  "edge": updated_edge_object,  "key": property_that_was_updated,  "old": old_value_of_that_property}

If the element contains information about a set vertex label, it's in the following format:

{  "event_type": "set_vertex_label",  "vertex": updated_vertex_object,  "label": label}

If the element contains information about a removed vertex label, it's in the following format:

{  "event_type": "removed_vertex_label",  "vertex": updated_vertex_object,  "label": label}

### Owner​

The user who executes the create query is going to be the owner of the trigger. Authentication and authorization are not supported in Memgraph Community, thus the owner will always be Null, and the privileges are not checked in Memgraph Community. In Memgraph Enterprise the privileges of the owner are used when executing openCypherStatements, in other words, the execution of the statements will fail if the owner doesn't have the required privileges. More information about how the owner affects the trigger can be found in the reference guide.

## Dropping a trigger​

A trigger can be removed by running the following query:

DROP TRIGGER trigger_name;

## Trigger info​

Users can get info about all the triggers by using the following query:

SHOW TRIGGERS;

which returns results in the following format:

trigger namestatementevent typephaseowner
name of the triggerstatement which the trigger executesevent which triggers the statementphase at which the trigger executes its statementowner of the trigger or Null