Insert query
An Insert query adds data to a database. You can insert an instance of a type, assign ownership of an attribute, or assign a new role player for a relation.
Insert queries can be used only in write transactions.
Behavior
An Insert query inserts new data into a TypeDB database using TypeQL patterns.
This is the only type of data query that can be used without a match
clause.
A match
clause in an Insert query matches existing concepts in a database to provide context for inserting new data
that is connected to existing data through relations, ownerships, values, types, etc.
An insert
clause is executed once per every result of preceding match
clause.
In particular, if there is no match in a database for a match
clause of an insert
query,
then there will be no inserts.
If there is no preceding match
clause, an insert
clause is executed once.
An insert query returns a Stream/Iterator of ConceptMap with the inserted data.
Inserted data must not violate a schema of a database.
Match clause
A match
clause is optional in an Insert query.
You can use a declarative and composable TypeQL pattern in a match
clause and TypeDB will find data that matches
the pattern.
For more information on a match
clause, see the
Match clause description on the Queries page.
For more information on patterns used in a match
clause, see the
Pattern syntax section.
Insert clause
An insert
clause is used in an Insert query to specify new data to be inserted into a TypeDB database.
This clause is executed exactly once for every result matched by the preceding match
clause of the same query,
or just once, if there is no preceding match
clause.
An insert
clause returns inserted data as a stream/iterator of ConceptMap.
Following the insert
keyword is a TypeQL pattern to define the inserted data.
A pattern in an insert
clause shares variables with a pattern from a preceding match
clause
An insert
clause can have multiple statements in its pattern to insert in one query.
But it can’t insert types
(use the define to insert new types) and can’t have the following:
-
Disjunction
-
Negation
-
is
keyword
A single simple statement of an insert
clause pattern can insert:
-
an instance of a type,
-
an ownership of an attribute, or
-
a new role player for an existing role of a relationship.
Inserting an ownership of an attribute that doesn’t exist in a database yet, implicitly inserts such an attribute.
For more information on patterns used in an insert
clause, see the examples section below.
For more information on patterns in general, see the Pattern syntax section.
Inserting instances
To insert an entity, attribute, or relation, you need to use the following isa
pattern in an insert
clause:
<variable> isa <type>;
Where <variable>
(e.g., $x
) — a query variable of an instance to insert;
<type>
(e.g., person
) — type of the inserted instance.
Inserting an attribute requires setting both type and value of a new attribute. You can specify the value as a separate statement (with an equal comparator) or in the same statement (by providing a value directly after a variable, using a whitespace as a separator). Alternatively, you can insert an attribute implicitly by assigning an ownership of non-existent attribute of a valid type.
Inserting a relation requires setting at least one of its role player references.
Existence of a relation often implies the existence of its role players for all its roles.
Inserting a relation without a role player for a role can create an incomplete data state.
Like a marriage
relation with only one known spouse.
See an example of inserting instances of data below.
Inserting ownerships
To insert an ownership of an attribute, you need to match or insert both the attribute and its future owner
and then use the following pattern in a insert
clause of the same query:
<owner-variable> has <attribute-variable>;
With this pattern, ownership of the attribute, represented by attribute-variable
, assigned to owner-variable
.
If the attribute with the attribute doesn’t exist, yet it is created/inserted implicitly by this query.
Attributes are immutable. Rather than changing a value of an owned attribute, you can delete an ownership of it and replace with an ownership of another attribute with a different value.
See an example of inserting ownership of an attribute below.
Adding role players to a relation
To add a role player reference to a relation, match or insert both the relation and the instance of data that
will play a role in it and then use the following pattern in a insert
clause of the same query:
<relation-variable> (<role>:<instance-variable>);
Where <relation-variable>
— a query variable of the relation to modify;
<role>
— an optional specification of a role of a role player to add;
<instance-variable>
— a query variable of a role player instance.
With this pattern, information that an existing instance plays a role in a specified relation is added. You can omit the role in a pattern if its unambiguous which role the referenced instance can play in the relation.
See an example of inserting role players from a relation.
Examples
Use the IAM schema and sample data for the following examples.
Inserting data with no matching
To insert new data with no connection to existing database data, we can use an Insert query without a match
clause:
insert $p isa person, has full-name "Bob";
The above query inserts a person
entity that owns a full-name
attribute whose value is "Bob".
If there is no such attribute in a database, then it will be created by this query implicitly. |
Matching in an Insert query
match
$p isa person, has full-name "Bob";
insert
$p has email "bob@vaticle.com";
The above query finds a person
entity that has the full-name
attribute with the value of Bob
and makes it the owner of the email
attribute with the value of bob@vaticle.com
.
If there is no person that matches the match
clause pattern, then there will be no information inserted by the query.
If there are multiple instances that match the pattern, then every matched person will be assigned ownership of the
email attribute.
Inserting entities
Use a variable followed by an isa
pattern with an entity type to insert an entity.
Entity insertion statement with isa
is usually combined with statements to assign attribute ownership
or roles in relations.
It is possible to insert an entity without any attribute ownership or roles played. But entities without any additional information associated with them are indistinguishable from one another. |
insert
$p isa person,
has full-name "John Parkson",
has email "john.parkson@gmail.com",
has credential "qwerty1";
The above query inserts a person
entity with the following attributes:
-
full-name
— value isJohn Parkson
, -
email
— value isjohn.parkson@gmail.com
, -
credential
— value isqwerty1
.
Inserting attributes
You can insert an attribute explicitly.
Use a variable followed by a value and isa
pattern with an attribute type to insert an attribute.
insert
$s 34 isa size-kb;
Attributes that are not owned by any other instances are called orphaned attributes and aren’t very useful to store in a database.
You can insert attributes implicitly by assigning ownership of an attribute that doesn’t exist yet.
Use the owner’s variable (with isa
pattern if it’s a new instance) followed by the has
keyword,
an attribute type, and a value to insert an ownership of an attribute
insert
$f isa file, has path "new-file.txt";
The above query inserts a new file
entity and assigning it an ownership of path
attribute
with the value of new-file.txt
.
If there was no such attribute prior to the query execution, it is inserted implicitly as a result of assigning
the ownership.
We can assign ownership of an attribute for an existing entity or relation by matching it first. See an example below.
match
$f isa file, has path "new-file.txt";
insert
$f has size-kb 331;
The above query matches a file
entity by its owned path
attribute and inserts size-kb
attribute
with the value of 331
.
If there was no such attribute first, it is created as a result of a query.
Note that we removed the |
Multivalued attributes
TypeDB supports multivalued attributes by allowing ownership of multiple attributes of the same type.
For example, if the person
entity type can own the email
attribute type, then an instance of the person
can own multiple (from zero to many) email
attributes with different values.
match
$p isa person, has full-name "John Parkson";
insert
$p has email "john.parkson@vaticle.com",
has email "admin@jp.com",
has email "jp@gmail.com";
This query will assign ownership of three different attributes of the email
type to the matched person
entity
from one of the previous examples: Inserting entities.
As a result, the matched entity should own six attributes, four of which are of email
type.
See the example of a Fetch query output, showing all attributes of the person with name John Parkson
below.
{
"p": {
"attribute": [
{ "value": "John Parkson", "value_type": "string", "type": { "label": "full-name", "root": "attribute" } },
{ "value": "admin@jp.com", "value_type": "string", "type": { "label": "email", "root": "attribute" } },
{ "value": "jp@gmail.com", "value_type": "string", "type": { "label": "email", "root": "attribute" } },
{ "value": "john.parkson@gmail.com", "value_type": "string", "type": { "label": "email", "root": "attribute" } },
{ "value": "john.parkson@vaticle.com", "value_type": "string", "type": { "label": "email", "root": "attribute" } },
{ "value": "qwerty1", "value_type": "string", "type": { "label": "credential", "root": "attribute" } }
],
"type": { "label": "person", "root": "entity" }
}
}
See the illustration of the resulted data from TypeDB Studio below.
Inserting relations
Use an optional variable followed by parenthesis with role players references with or without role types.
After the parenthesis, use an isa
pattern with a relation type.
Inserting a relation requires specifying at least one role player.
Roles in a relation are expected to be played by existing or new entities, other relations, or attributes.
A role player can be matched by a preceding match
clause or inserted by the same insert
clause.
match
$op isa operation, has name "view_file";
insert
$f isa file, has path "new-relation.txt";
$a (object: $f, action: $op) isa access;
In the above example we match the view_file
operation and insert the new-relation.txt
file to insert a relation
between them with roles object
and action
respectively.
We can insert a relation with some roles missing a role player, but that represents an incomplete data state. The existence of a relation suggests the existence of its role players.
Multiple role players
A role in a relation can be played more than once (by multiple role players).
match
$p1 isa subject, has full-name "Pearle Goodman";
$p2 isa subject, has full-name "Masako Holley";
$o isa object, has path "zewhb.java";
insert
$obj-ownership (owner: $p1, owner: $p2, object: $o) isa object-ownership;
The above query:
-
Finds the
person
entity ($p1
) by itsfull-name
attributePearle Goodman
. -
Finds the
person
entity ($p2
) by itsfull-name
attributeMasako Holley
. -
Finds the
object
entity ($o
) by itspath
attributezewhb.java
. -
Inserts an
object-ownership
relation ($obj-ownership
) which relates$p1
(asowner
) and$p2
(asowner
) to$o
(asobject
).
In short, it makes Pearle Goodman
and Masako Holley
owners of the zewhb.java
file.
Adding role players
We can add (insert) a new role player reference for an existing relation.
match
$p1 isa subject, has full-name "Pearle Goodman";
$p2 isa subject, has full-name "Masako Holley";
$o isa object, has path "zewhb.java";
$obj-ownership (owner: $p1, owner: $p2, object: $o) isa object-ownership;
$p3 isa subject, has full-name "Kevin Morrison";
insert
$obj-ownership (owner: $p3);
The above query:
-
Finds the
person
entity ($p1
) by itsfull-name
attributePearle Goodman
. -
Finds the
person
entity ($p2
) by itsfull-name
attributeMasako Holley
. -
Finds the
object
entity ($o
) by itspath
attributezewhb.java
. -
Finds the
object-ownership
relation ($obj-ownership
) which relates$p1
(asowner
) and$p2
(asowner
) to$o
(asobject
). -
Finds the
person
entity ($p3
) by itsfull-name
attributeKevin Morrison
. -
Adds
$p3
as a role player for theowner
role of the$obj-ownership
relation.
Relations as role players
In addition to entities and attributes, a role of a relation can be played by another relation.
match
$s isa subject, has full-name "Pearle Goodman";
$o isa object, has path "zewhb.java";
$a isa action, has name "modify_file";
$ac (object: $o, action: $a) isa access;
insert
$p (subject: $s, access: $ac) isa permission;
The above query:
-
Finds the
subject
($s
) with thefull-name
attribute with the value ofPearle Goodman
. -
Finds the
object
($o
) with thepath
attribute with the value ofzewhb.java
. -
Finds the
action
($a
) whose name attribute has a value ofmodify_file
. -
Finds the
access
relation ($ac
) that relates the$o
(asobject
) to$a
(asaction
). -
Inserts a
permission
relation that relates$s
(assubject
) to the relation$ac
(asaccess
).
In short, it creates the permission
that lets Pearle Goodman
to modify the zewhb.java
file.
The relation of access
type now plays the role of access
in the inserted relation of the permission
type.