Advanced patterns & queries

Pattern syntax

Schema

The statements below can be used as standalone patterns or combined with other statements to find types defined in a database’s schema. Use the Define query to try them.

What we are looking for in a schema Pattern syntax Example

Type

$<var_label> type <type>;

$t type person;

Type or subtype

$<var_label> sub <type>;

$t sub subject;

Direct subtype

$<var_label> sub! <type>;

$t sub! subject;

Role in a relation type

<relation> relates $<var_label>;

permission relates $r;

Role player’s type in a relation

$<var_label> plays <relation>:<role>;

$r plays permission:subject;

Owner type of an attribute type

$<var_label> owns <attr-type>;

$o owns full-name;

Attribute subtype

$<var> sub[!] <attribute-type> [, value <value-type>];

$s sub id, value string;

Data

The statements below can be used as a standalone patterns or in a combination with other statements to find data in a database. Use the Get query to try them.

What we are looking for in data Pattern syntax Examples

Instance of a type or a subtype

$<var_label> isa <type> [, <has-attribute statement>...];

$p isa person, has $a;

Instance of a type

$<var_label> isa! <type> [, <has-attribute statement>...];

$p isa! person, has $a;

Instance of an attribute type

$<var_label> [isa[!] <attr-type>] (contains "<text>" | like "<regex>" | <value>) [, <has-attribute statement>...];

  • $a "Kevin Morrison";

  • $b isa full-name;

  • $c contains "Kevin";

Instance of a relation

[$<var_label>] ([<role>:] $<var_label> [, [<role>:] $<var_label>]...) isa <relation-type> [, <has-attribute statement>...];

$pe (subject: $p, access: $ac) isa permission, has validity true;

has-attribute statement

has <attr-type> ($<var_label> | [<comparison-operator>] <value> );

$f has size-kb > 300;

comparison

$<var_label> [<comparison-operator>] <value>;

$a > 300; $f has size-kb $a;

equal

$<var_label> is $<var_label>;

$p isa person, has $a; $t isa entity; $t is $p; get $t;

For more information on comparison operators, computation, and combining statements — see the Pattern matching essentials page.

Matching patterns examples

The patterns below are designed for the IAM schema and dataset, but they can return any number of results:

  • zero,

  • one,

  • multiple.

Schema

Type matching

All types

Use a subtype pattern with the built-in type thing to find all types defined in a schema. For more information, see the Thing type section.

match $t sub thing;

The thing internal type will be deprecated in one of the upcoming versions and deleted in TypeDB version 3.0.

Consider using entity, attribute, or relation built-in types instead.

To produce the same result as the above example, use the following query:

match $s sub $t; {$t type entity;} or {$t type relation;} or {$t type attribute;};
Specific type or nested subtype

Use a subtype pattern to find a specific type and all of its subtypes.

match $o sub object;

The above pattern finds the object type and all of its nested subtypes: direct (i.e., resource and resource-collection) and indirect (i.e., file, interface, directory, and application).

Direct subtypes

Use a subtype pattern with an exclamation mark (!) to find the direct subtypes of a specific type.

match $o sub! object;

The above query finds all direct subtypes of the object type (i.e., resource and resource-collection).

Attribute types (by value type)

Use an attribute subtype pattern to find all attribute types with a specific value type.

match $a sub attribute, value boolean;

The above query finds all attribute types that have a boolean value type.

Specific type

Use a type pattern to find a specific type, excluding any nested subtypes (direct or indirect).

match $o type object;

The above query returns the object type, and none of its nested subtypes (direct or indirect).

Players of a specific role

Use a "players type in a relation" pattern to find all types that play a specific role in a specific relation type.

match $p plays permission:subject;

The above query finds all types that can play the subject role in the permission relation type.

Owners of a specific attribute type

Use an owners of attribute type pattern to find all types that own a specific attribute type.

match $o owns full-name;

The above query finds all types that own the full-name attribute.

Role matching

Use the role types in a relation pattern to find all roles in a specific relation.

match permission relates $r;

The above query finds all the roles defined in the permission relation type (permission:access and permission:subject).

Data

All data

Use an instance pattern with type thing to find all entities, relations, and attributes (instances of data).

match $t isa thing;

For more information on thing type see the Thing type section.

The thing internal type will be deprecated in one of the upcoming versions and deleted in TypeDB version 3.0.

Consider using entity, attribute, or relation built-in types instead.

To produce the same result as the above example, use the following query:

match $s sub $t; {$t type entity;} or {$t type relation;} or {$t type attribute;};

Entity matching

Instances of the specific type or its subtypes

Use an instance pattern to find all entities of a specific entity type (and of all its subtypes).

match $p isa person;

The above query returns all entities of the person entity and any of its subtypes.

The isa keyword will return all direct and indirect (of all subtypes of the given type) instances. To limit results to only direct instances of the given type use isa! instead. See the example below.

Instances of the specific type only

Use an instance pattern with an exclamation mark (!) to find all entities of a specific type only (and none of its subtypes).

match $u isa! user;

The above query finds all user entities. It excludes any entities whose type is a subtype of user, so person entities would not be included.

Owners of a specific attribute type

Use an instance pattern with has-attribute statement pattern to find all entities that own an attribute of a specific type.

match $p isa person, has full-name $n;

The above query finds all person entities that own a full-name attribute.

Owners of specific attribute types (multiple)

Use an instance pattern with multiple has-attribute statements to find all entities that own a specific set of attributes, each of a specific type.

match $p isa person, has full-name $n, has email $email, has credential $cr;

The above query finds all person entities that have full-name, email, and credential attributes.

Owners of a specific attribute (by type and value)

Use an instance pattern with has-attribute statement pattern to find all entities that own a specific attribute with a specific value.

match $p isa person, has full-name “Kevin Morrison”;

The above query finds all person entities that have a full-name attribute with a value of “Kevin Morrison”.

Owners of a specific attribute (by type and value range)

Use an instance pattern with a has-attribute statement containing a comparison operator to find all entities that have a specific attribute whose value is within a specific range.

match $f isa file, has size-kb < 100;

However, if the attribute value itself is required in the query response, combine a has-attribute statement (with no comparison operation) with a separate comparison pattern.

match
  $f isa file, has size-kb $s;
  $s < 100;

Relation matching

The pattern used to find relations is different from the one used to find entities because relations have role players (entities, other relations, and/or attributes).

Role players

Use a relation pattern with a matched role player to find all relations of a specific type that relate a specified instance.

match
  $p isa person, has full-name "Kevin Morrison";
  $pe (subject: $p) isa permission;

The above query finds all person entities ($p) owning a full-name attribute with a value of Kevin Morrison and then it finds all permission relations ($pe) in which those entities $p play the subject role.

Owners of a specific attribute (with value)

Use a relation pattern with a has-attribute statement to find all relations of a specific type and which have a specific attribute with a specific value.

match $pe (subject: $p, access: $ac) isa permission, has validity true;

The above query finds all permission relations which have a validity attribute whose value is true.

With no relation variable

The relation variable can be omitted when only the role players are needed.

match (subject: $p, access: $ac) isa permission;
With no role names

The names of a relation’s roles can be omitted.

match $pe ($p, $ac) isa permission;

This will match any valid combination of roles.

Attribute matching

There are multiple ways to find attributes depending on the use case.

Value

Use a variable and an attribute value to find all attributes with a specific value.

match $x "Masako Holley";

The above query finds all attributes with a value of “Masako Holley”, regardless of their type.

Type and value

Combine an attribute pattern with a comparison pattern to find all attributes of a specific type and with a specific value.

match
  $n isa full-name;
  $n "Masako Holley";

Or use this compact form:

match $n "Masako Holley" isa full-name;

The above queries finds all full-name attributes with a value of Masako Holley.

Value containing

Use an attribute pattern with contains keyword to find all attributes whose value contains specific string.

match $name contains "Masako";

The above query finds all attributes whose value contains the text Masako, regardless of their type.

Value matching regex

Use an attribute pattern with like keyword and a regular expression to find all attributes whose value matches the specified regular expression pattern.

match $x like "(Masako Holley|Kevin Morrison)";

The above query finds all attributes whose value is Masako Holley or Kevin Morrison, regardless of their type.

Equality

Use an equal pattern to check if two variables represent the same instance (or instances). That not only means equality by type and value but literary being the same instance(s) of data in a database. It is often helpful in negation.

match
  $x isa person;
  $y isa person;
  not { $x is $y; };

The above query returns pairs of users that are not the same user.

Computation

Using parentheses
match
  $f isa file, has size-kb $s;
  ?x = ($s + 5) * 2;

In the above example parentheses are used to change order of operations: addition inside the parentheses will happen before multiplication.

Using exponentiation
match
  $f isa file, has size-kb $s;
  ?x = $s ^ 2;

In the above example we set value variable ?x to be equal to the result of exponentiation: value of $s raised to the power of 2.

Using multiplication
match
  $f isa file, has size-kb $s;
  ?x = $s * 3;

In the above example we multiply the value of $s by 3 and set the value variable ?x to be equal to the result.

Using division
match
  $f isa file, has size-kb $s;
  ?x = $s / 3;

In the above example we divide the value of $s by 3 and set the value variable ?x to be equal to the result.

Using modulo
match
  $f isa file, has size-kb $s;
  ?x = $s % 3;

In the above example we set the value variable ?x to be equal to the result of modulo operation between $s and 3. Or $s mod 3.

Using addition
match
  $f isa file, has size-kb $s;
  ?x = $s + 1250;

In the above example we add the value of $s to 1250 and set the value variable ?x to be equal to the result.

Using subtraction
match
  $f isa file, has size-kb $s;
  ?x = $s - 300;

In the above example we subtract 300 from the value of $s and set the value variable ?x to be equal to the result.

Using minimum function
match
  $f isa file, has size-kb $s;
  ?x = $s - 300;
  ?a = min($s, ?x);

In the above example we set the value variable ?x to be equal to either $s or ?x, whichever is the minimum.

Using maximum function
match
  $f isa file, has size-kb $s;
  ?x = $s - 300;
  ?a = max($s, ?x);

In the above example we set the value variable ?x to be equal to either $s or ?x, whichever is the maximum.

Using floor function
match
  $f isa file, has size-kb $s;
  ?x = floor($s / 3);

In the above example we set the value variable ?x to be equal to the result of floor function (the greatest integer less than or equal to the argument).

Using ceiling function
match
  $f isa file, has size-kb $s;
  ?x = ceil($s / 3);

In the above example we set the value variable ?x to be equal to the result of ceiling function (the least integer greater than or equal to the argument).

Using rounding function
match
  $f isa file, has size-kb $s;
  ?x = round($s / 3);

In the above example we set the value variable ?x to be equal to the result of rounding function (rounding to the nearest integer, half up).

Using absolute value function
match
  $f isa file, has size-kb $s;
  ?x = abs($s - 1000);

In the above example we set the value variable ?x to be equal to the result of absolute value function (discarding the sign).

Conjunctions

By default, a collection of statements in a match clause, divided by semicolons, constructs a conjunction of statements.

match
  $p isa person, has full-name "Kevin Morrison";
  $o isa object, has path $o-path;
  $ac(object: $o) isa access;
  $pe(subject: $p, access: $ac) isa permission;

The above example uses conjunction to ensure all statements are matched:

  1. Find all person entities ($p) that have a full-name attribute whose value is Kevin Morrison.

  2. Find all object entities ($o) that have a path attribute ($o-path).

  3. Find all access relations ($ac) where $o plays the object role.

  4. Find all permission relations ($pe) where $p plays the subject role, $ac the access role.

The object entities are limited to those which play the object role in access relations, which are themselves limited to those which play the access role in permission relations. The permission relations are limited to those in which matching person entities play the subject role.

Disjunctions

To include statements in the form of a disjunction, we need to wrap each statement in {} and place the or keyword in between them.

match
  $p isa person, has full-name $n;
  { $n contains "Masako"; } or { $n contains "Kevin"; };
get $p;

The above query uses disjunctions to ensure one of two statements are matched:

  1. Finds all person entities that have a full-name attribute ($n).

  2. Checks to see if $n contains the text “Masako” OR if $n contains the text “Kevin”:

    • If either statement is true, there is a match.

    • If neither statement is true, there is NO match.

The person entities are limited to those that have a full-name attribute whose value contains Masako or Kevin.

Complex example

To better illustrate the possibilities, we will now look at an example of a more complex pattern.

Complex example

The pattern is a conjunction of five different pattern types:

  1. Conjunction 1 specifies the variables for two person instances, their full-names, action, and file that has path README.md, specifies their types.

  2. Disjunction specifies that the actions of interest are either modify_file or view_file.

  3. Negation 1 specifies that person $p1 shall not have full-name with value of Masako Holley.

  4. Negation 2 specifies that person $p2 shall not have full-name with value of Masako Holley.

  5. Conjunction 2 defines the pattern requiring the file to have access with action that we specified earlier, and both instances of person to have a permission to the specified access.

In short, the above example finds pairs of people who both have permission to access the same file with a path of README.md. The pattern additionally specifies both of them to not have name Masako Holley and the access to be either modify_file or view_file.

Query examples

Use the examples below to try different types of queries to a database’s data (querying for data instances).

Get query

match
  $p isa person, has full-name $f, has email $e;
get $p, $e;
group $p;
count;

The above example retrieves all instances of the person type, that have ownership over at least one instances of full-name attribute type and at least one instance of email attribute. We then filter the response to contain only the $p and the $e in every result. We further add modifiers to group results by the $p variable and count the number of results in every group.

The resulted response should look like this:

iid 0x826e800f8000000000000000 isa person => 1
iid 0x826e800f8000000000000001 isa person => 1
iid 0x826e800f8000000000000002 isa person => 1

In the example above we got an answer of the number of emails for every person with an email and full-name in the database.

Without modifiers the response would look like the following:

{
    $p iid 0x826e800f8000000000000001 isa person;
    $e "[email protected]" isa email;
}
{
    $p iid 0x826e800f8000000000000002 isa person;
    $e "[email protected]" isa email;
}
{
    $p iid 0x826e800f8000000000000000 isa person;
    $e "[email protected]" isa email;
}

The iid field is an internal id, used to address in query results different instances that doesn’t have a value.

It should not be used for any logic as there are no guarantees provided regarding it. It may be deprecated in future versions of TypeDB.

For more information on how to use the Get query please see the Get query page.

Insert query

To write new data to a database use the insert query.

insert
  $p isa person, has email "[email protected]", has full-name "Bob";

The above query inserts compeltely new data of an instance of the person entity type that has email attribute with the value [email protected] and full-name attribute with the value Bob.

To add data to the existing one we can use the optional match clause in the insert query:

match
  $p isa person, has full-name "Bob";
insert
  $p has email "[email protected]";

The above example matches all instances of the person type and all its subtypes that have a full-name attribute with the value of Bob.

Then it inserts the additional data that all matched instances of person have ownership over the email attribute type instance with the value [email protected].

For more information on the Insert query please see the Insert query page.

Delete query

To delete data from a database use the delete query.

match
  $p isa person, has full-name "Bob", has email $e;
  $e "[email protected]";
delete
  $p has email $e;

The above example matches all instances of the person type and all its subtypes that have ownership over at least one instance of full-name attribute type with the value Bob and at least one instance of the email type with the value equal to the $e variable. The $e variable is set to have a value of [email protected].

For all matched results the query deletes the exact ownership of the email instance with the value equal to the $e by the $p. The person instance in $p and the email instance in $e continue to exist in the database. Only the ownership between them gets deleted.

For more information on how to delete data please see the Delete query page.

Update

To update data in a database we use a combined match-delete-insert query.

match
  $p isa person, has full-name "Bob", has email $email;
delete
  $p has $email;
insert
  $p has email "deleted";

The above example matches all instances of the person type and all its subtypes that have a full-name attribute with the value Bob and have ownership over at least one instance of the email attribute type.

It proceeds with deleting the ownership of any matched email attribute instances that the matched person instances have.

Finally, it inserts the data that all matched instances of person type have ownership over the email attribute with the value deleted.

The $email variable can only have one concept for every matched pattern (solution for the match clause). So if there will be more than one e-mail matched, then the result of match clause will contain multiple solutions.

Both delete clause and insert clause will be executed once for every matched pattern. But the insertion of ownership of the instance of the email attribute type with the same value twice will not produce any duplication. Because any attribute instance can be owned only once by the same owner. Hence, all previously existent "email" attributes will be deleted and only one inserted.

For more information on how to use the Update query see the Update query page.

Complex pattern query example

A match clause can only address data or types that already exist in a database.

The declarative nature of the TypeQL pattern means that if one of the match clause statements can’t find any instances in a database that might lead to finding no matches/solutions/answers to a query with that pattern.

For example:

match
  $p isa person, has full-name $p-fname;
  $o isa object, has path $o-path;
  $a isa action, has name "view_file";
  $ac(object: $o, action: $a) isa access;
  $pe(subject: $p, access: $ac) isa permission;
  $p-fname = "Kevin Morrison";

The above query does the following:

  1. Finds all person entities ($p) that have full-name attribute with the value of $p-fname variable, that is later set as string Kevin Morrison. There is actually only one such person in the IAM database by default.

  2. Finds all object entities ($o) that have path attribute ($o-path). The value of the attribute is not limited but assigned a variable $o-path.

  3. Finds all action entities ($a) that have name attribute with the value of view_file. There is actually only one such action in the IAM database by default.

  4. Finds all access relations ($ac) that relate $o (as object role) to $a (as action role).

  5. Finds all permission relations ($pe) that relate $p (as subject role) to $ac (as access role).

  6. States that $p-fname variable equals by value to a string Kevin Morrison.

This match clause can be a part of any query. For example, by appending a delete $pe isa permission statement we can create a delete query that deletes all access to action view_file on all objects with any path attribute owned for a person Kevin Morrison.

If we change the value of the $p-fname variable to something nonexistent in our database then the match clause will return no results. Appending the same delete statement to such match clause would create a useless query that can’t delete anything because it can’t match any data to delete.