Officially out now: The TypeDB 3.0 Roadmap >>

Deleting data

This page explains how to delete data from a TypeDB database.

Understanding delete pipeline stages

A delete stage is used to delete data from a TypeDB database. It can be used in a pipeline to operate variables declared on a preceding match stage.

Refer to the Delete stage page for detailed explanation and more examples.

Sending delete pipelines

The examples below can be combined with the following schema file. A part of this file is defined in the respective definition manuals. Also, the data deleted in these examples is inserted in the insertion manual.

See the schema.tql
schema.tql
define
  entity content @abstract,
    owns id @key;

  entity page @abstract, sub content,
    owns page-id,
    owns name,
    owns bio,
    owns profile-picture,
    plays posting:page,
    plays following:page;

  entity profile @abstract, sub page,
    owns username,
    owns name @card(0..3),
    plays group-membership:member,
    plays location:located,
    plays content-engagement:author,
    plays following:follower;

  entity user sub profile,
    owns email,
    owns phone @regex("^\d{8,15}$") @unique,
    owns karma,
    owns relationship-status,
    plays friendship:friend,
    plays family:relative,
    plays relationship:partner,
    plays marriage:spouse,
    plays employment:employee;

  relation social-relation @abstract,
    relates related @card(0..);

  relation friendship sub social-relation,
    relates friend as related @card(0..);

  relation family sub social-relation,
    relates relative as related @card(0..1000);

  relation relationship sub social-relation,
    relates partner as related,
    owns start-date;

  relation marriage sub relationship,
    relates spouse as partner,
    owns exact-date,
    plays location:located;

  entity organisation sub profile,
    owns tag @card(0..100),
    plays employment:employer;

  entity company sub organisation;
  entity charity sub organisation;

  relation employment,
    relates employer,
    relates employee,
    owns start-date,
    owns end-date;

  entity group sub page,
    owns group-id,
    owns tag @card(0..100),
    plays group-membership:group;

  relation group-membership,
    relates group,
    relates member,
    owns start-timestamp,
    owns end-timestamp;

  entity post @abstract, sub content,
    owns post-id,
    owns post-text,
    owns creation-timestamp @range(1970-01-01T00:00:00..),
    owns tag @card(0..10),
    plays posting:post,
    plays commenting:parent,
    plays reaction:parent,
    plays location:located;

  entity text-post sub post;

  entity image-post sub post,
    owns post-image;

  entity comment sub content,
    owns comment-id,
    owns comment-text,
    owns creation-timestamp,
    owns tag @card(0..5),
    plays commenting:comment,
    plays commenting:parent,
    plays reaction:parent;

  relation interaction @abstract,
    relates subject @abstract,
    relates content;

  relation content-engagement @abstract, sub interaction,
    relates author as subject;

  relation posting sub content-engagement,
    relates page as content,
    relates post @card(0..1000);

  relation commenting sub content-engagement,
    relates parent as content,
    relates comment;

  relation reaction sub content-engagement,
    relates parent as content,
    owns emoji @values("like", "love", "funny", "surprise", "sad", "angry"),
    owns creation-timestamp;

  relation following,
    relates follower,
    relates page;

  entity place,
    owns place-id,
    owns name,
    plays location:place;

  entity country sub place,
    plays city-location:parent;

  entity city sub place,
    plays city-location:city;

  relation location,
    relates place,
    relates located;

  relation city-location sub location,
    relates parent as place,
    relates city as located;

  attribute id @abstract, value string;
  attribute page-id @abstract, sub id;
  attribute username sub page-id;
  attribute group-id sub page-id;
  attribute post-id sub id;
  attribute comment-id sub id;
  attribute place-id sub id;

  attribute name value string;
  attribute email value string @regex("^.*@\w+\.\w+$");
  attribute phone value string;
  attribute karma value double;
  attribute relationship-status value string @values("single", "married", "other");
  attribute latitude value double;
  attribute longitude value double;

  attribute event-date @abstract, value datetime;
  attribute start-date sub event-date;
  attribute end-date sub event-date;
  attribute exact-date @abstract, sub event-date;

  attribute payload @abstract, value string;
  attribute text-payload @abstract, sub payload;
  attribute image-payload @abstract, sub payload;
  attribute bio sub text-payload;
  attribute comment-text sub text-payload;
  attribute post-text sub text-payload;
  attribute post-image sub image-payload;
  attribute profile-picture sub image-payload;

  attribute tag value string;
  attribute emoji value string;

  attribute creation-timestamp value datetime;
  attribute start-timestamp value datetime;
  attribute end-timestamp value datetime;

  fun all_relatives($user: user) -> { user }:
    match
      $relative isa user;
      {
        family (relative: $user, relative: $relative);
      } or {
        let $intermediate in all_relatives($user);
        family (relative: $intermediate, relative: $relative);
      };
      return { $relative };

Delete an instance

To delete data, open a write transaction. This allows you to read and write data to your database while keeping the schema secure.

Every deletion begins with an delete, but also requires some input, so a preceding match stage is needed to produce concepts incoming to the delete stage. The logic is similar to inserting data based on a match: the variables, declared in the match stage, can be used in the delete stage to control the deletion process.

Similarly, multiple statements can be combined to delete multiple instances or connections.

To delete a type instance (an entity, a relation, or an attribute), declare a $var for this instance and add delete $var:

User deletion example
match
  $u isa user, has username "User";
delete
  $u;

The following pipeline will act in two stages:

  • The first stage will match all user s with username "User" (as username is a key in the schema, you can be ensured that only one user will be found).

  • The second stage will delete the matched user s (the only user with username "User").

Take into account that default relations and attributes without certain annotations can be cleaned up on commit if they are not relating or owned by any other instance, so deleting a single entity can lead for more cascading cleanups.

For example, the @independent annotation can help preserving attributes (username) in the database even if their owners are deleted.

Similarly to insert stages, delete s have the same sets of data constraints to check after every operation or before a commit.

Delete an instance’s ownership

To delete only a specific trait instance, mention what you want to delete and what instance it relates to. In case of an ownership instance, write an expression like has $attribute of $owner using the has statement and the keyword of pointing to the owner:

User’s ownership of an attribute deletion example
match
  $a isa user, has username "Alice", has email $email;
delete
  has $email of $a;

This query only deletes the has between $email and $a, not the attribute itself! However, if email s are not @independent and there will be no users with this email on commit, the attribute will also be deleted.

The verbose way to delete both the ownership and the attribute is:

User’s ownership of an attribute with the attribute itself deletion example
match
  $a isa user, has username "Alice", has email $email;
delete
  has $email of $a;
  $email;

However, it is redundant as the deletion of an instance also deletes all its connections. Thus, it can be written as:

Deletion of an attribute example
match
  $a isa user, has username "Alice", has email $email;
delete
  $email;

Delete a relation connection

Similarly, a connection between a relation and its roleplayers can be deleted. A single role or multiple roles can be deleted using the following query:

Deletion of a relation linking example
match
  $b isa user, has username "Bob", has email "bob@typedb.com";
  $c isa user, has username "Charlie", has email "charlie@typedb.com";
  $f isa friendship, links (friend: $b, friend: $c);
delete
  links ($b, $c) of $f;
  links ($b) of $f;

The has and links keywords are optional, but sometimes required for ambiguity resolution and are generally better for readability.

Response interpretation

A delete stage takes the input from the previous pipeline stages, processes the deletions and returns the concepts left from the input. All the deleted concepts are not shown in the output. This way, another pipeline stage can take this as an input and continue data processing.

For example, the example of a user instance deletion where there are no concepts left for the output produces the following TypeDB Console’s response:

Result with empty columns
No columns to show

At the same time, a has deletion does not affect the output, as both concepts are still in the database until a commit:

Result after a has deletion
   ------------
    $email | alice@typedb.com isa email
    $u     | iid 0x1e00030000000000000002 isa user
   ------------

However, if you delete the email itself:

Result after an attribute deletion
   ------------
    $u     | iid 0x1e00030000000000000002 isa user
   ------------

Preserving or reverting changes

Do not forget to commit your transaction to preserve the changes. As mentioned earlier, some data constraints are only validated upon commit. This means you might discover inconsistencies in your data during the commit process, and the commit will be rejected.

While most validations occur during operation time to keep data synchronized, commit-time validations are necessary to allow flexible data modifications. For example, validating inserted data against cardinality during operation time could block modifications entirely.

If you want to abort your changes, simply close the transaction or perform a rollback. Refer to Transactions for more details.

Having troubles?

Refer to the Debugging queries page for common debugging tips.