Officially out now: The TypeDB 3.0 Roadmap >>

Insert query

In this guide, you’ll see how to insert data in a database using Studio, Console, or one of the drivers.

Understanding Insert queries

An Insert query is used to insert data into a TypeDB database. An insert clause is executed once per every result matched by the match clause of the same query. If the match clause is omitted, then the insert clause is executed exactly once. For a detailed explanation of the query see the Delete query page.

Sending Insert queries

Before you start, make sure you followed the instructions from the Defining schemas section. The easiest way to send an Insert query is to use Studio or Console:

  • Studio

  • Console

Follow the Studio manual to connect to TypeDB and select a project folder. Then use the steps below:

  1. Use a drop-down list in the top toolbar to select a database.

  2. Switch to data session and write transaction types.

  3. Open a new tab and insert or type in an Insert query, for example:

    TypeQL Insert query
    insert
    $user1 isa user, has name "Alice", has email "alice@typedb.com";
    $user2 isa user, has name "Bob", has email "bob@typedb.com";
    $friendship (friend:$user1, friend: $user2) isa friendship;
  4. Run the query by clicking the studio run Run Query button.

  5. Commit the changes by clicking the studio check Commit query button.

  1. Open a data session and write transaction to the selected database (e.g., sample_db):

    transaction sample_db data write
  2. Send the Insert query:

    insert
    $user1 isa user, has name "Alice", has email "alice@typedb.com";
    $user2 isa user, has name "Bob", has email "bob@typedb.com";
    $friendship (friend:$user1, friend: $user2) isa friendship;

    Push Enter twice to send the query.

  3. Commit the changes:

    commit

To send an Insert query programmatically, use drivers:

  • Rust

  • Python

  • Node.js

  • Java

  • C#

  • C++

  • C

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the transaction.query().insert() method:
let databases = DatabaseManager::new(driver);
let db = databases.get(DB_NAME)?;
{
    let session = Session::new(db, SessionType::Data)?;
    {
        let tx = session.transaction(TransactionType::Write)?;
        let insert_query = "
                            insert
                            $user1 isa user, has name 'Alice', has email 'alice@typedb.com';
                            $user2 isa user, has name 'Bob', has email 'bob@typedb.com';
                            $friendship (friend:$user1, friend: $user2) isa friendship;
                            ";
        let _ = tx.query().insert(insert_query)?;
        tx.commit().resolve()?;
    }
}

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the transaction.query.insert() method:
with driver.session(DB_NAME, SessionType.DATA) as session:
    with session.transaction(TransactionType.WRITE) as tx:
        insert_query = """
                        insert
                        $user1 isa user, has name "Alice", has email "alice@typedb.com";
                        $user2 isa user, has name "Bob", has email "bob@typedb.com";
                        $friendship (friend:$user1, friend: $user2) isa friendship;
                        """
        response = list(tx.query.insert(insert_query))
        tx.commit()

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the transaction.query.insert() method:
try {
    session = await driver.session(DB_NAME, SessionType.DATA);
    try {
        tx = await session.transaction(TransactionType.WRITE);
        const insert_query = `
                            insert
                            $user1 isa user, has name "Alice", has email "alice@typedb.com";
                            $user2 isa user, has name "Bob", has email "bob@typedb.com";
                            $friendship (friend:$user1, friend: $user2) isa friendship;
                            `;
        await tx.query.insert(insert_query);
        await tx.commit();
    }
    finally {if (tx.isOpen()) {await tx.close()};}
}
finally {await session?.close();}

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the transaction.query().insert() method:
try (TypeDBSession session = driver.session(DB_NAME, TypeDBSession.Type.DATA)) {
    try (TypeDBTransaction tx = session.transaction(TypeDBTransaction.Type.WRITE)) {
        String insertQuery = """
                            insert
                            $user1 isa user, has name "Alice", has email "alice@typedb.com";
                            $user2 isa user, has name "Bob", has email "bob@typedb.com";
                            $friendship (friend:$user1, friend: $user2) isa friendship;
                            """;
        tx.query().insert(insertQuery);
        tx.commit();
    }
}

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the `transaction.Query.Insert() method:
using (ITypeDBSession session = driver.Session(DB_NAME, SessionType.Data)) {
    using (ITypeDBTransaction tx = session.Transaction(TransactionType.Write)) {
        string insert_query = @"
                                insert
                                $user1 isa user, has name 'Alice', has email 'alice@typedb.com';
                                $user2 isa user, has name 'Bob', has email 'bob@typedb.com';
                                $friendship (friend:$user1, friend: $user2) isa friendship;";
        _ = tx.Query.Insert(insert_query).ToList();
        tx.Commit();
    }
}

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the `transaction.query.insert()` method:
TypeDB::Options options;
TypeDB::Session session = driver.session(DB_NAME, TypeDB::SessionType::DATA, options);
{
    TypeDB::Transaction tx = session.transaction(TypeDB::TransactionType::WRITE, options);
    std::string insertQuery = R"(
                            insert
                            $user1 isa user, has name "Alice", has email "alice@typedb.com";
                            $user2 isa user, has name "Bob", has email "bob@typedb.com";
                            $friendship (friend:$user1, friend: $user2) isa friendship;
                            )";
    TypeDB::ConceptMapIterable result = tx.query.insert(insertQuery);
    tx.commit();
}

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the `query_insert()` function:
Options* opts = options_new();
session = session_new(databaseManager, DB_NAME, Data, opts);
tx = transaction_new(session, Write, opts);
if (tx == NULL || FAILED()) {
    handle_error("Transaction failed to start.");
    goto cleanup;
}
char query[512];
snprintf(query, sizeof(query), "insert $user1 isa user, has name 'Alice', has email 'alice@typedb.com'; $user2 isa user, has name 'Bob', has email 'bob@typedb.com'; $friendship (friend:$user1, friend: $user2) isa friendship;");
ConceptMapIterator* insertResult = query_insert(tx, query, opts);
if (FAILED()) {
    handle_error("Query execution failed.");
    goto cleanup;
}
void_promise_resolve(transaction_commit(tx));
if (FAILED()) {
    handle_error("Transaction commit failed.");
    goto cleanup;
}
session_close(session);

Response interpretation

An Insert query returns all concepts that got inserted into the database as a stream of ConceptMap objects.

Let’s say we send the following Insert query with a match clause:

Match-insert query example
match
$u isa user, has name "Bob";
insert
$new-u isa user, has name "Charlie", has email "charlie@typedb.com";
$f($u,$new-u) isa friendship;

With the data inserted earlier on this page, we should match only one such user with the name "Bob". That leads to inserting one new user and one relevant relation. If multiple matches are made by the match clause, then the insert clause runs for each of them.

To check the number of times an Insert query gets executed, you can either check its response or send a read query with the same matching pattern.

The response is a Stream/Iterator of ConceptMap objects. One ConceptMap object for every execution of the insert clause. A ConceptMap object maps every variable from the insert clause of the query to a concept in a database.

The easiest way to check the response for the query is to use a TypeDB client: Studio or Console. Send the above match-insert query the same way as the previous query.

Both Studio and Console should produce similar results:

{
    $bob iid 0x826e80018000000000000004 isa user;
    $f iid 0x847080017fffffffffffffff (friend: iid 0x826e80018000000000000002, friend: iid 0x826e80018000000000000004) isa friendship;
    $alice iid 0x826e80018000000000000002 isa user;
}

To process the response of an Insert query programmatically, you need to collect the response and iterate through it with a TypeDB driver. The number of iterations is equal to the number of the insert clause executions and every iteration returns a ConceptMap object with inserted data.

Let’s see an example of programmatically processing the response, where we commit the transaction only if the number of inserts meets our expectation.

Process Insert query response
  • Rust

  • Python

  • Node.js

  • Java

  • C#

  • C++

  • C

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the transaction.query().insert() method:
let databases = DatabaseManager::new(driver);
let db = databases.get(DB_NAME)?;
{
    let session = Session::new(db, SessionType::Data)?;
    {
        let tx = session.transaction(TransactionType::Write)?;
        let match_insert_query = "
                                match
                                $u isa user, has name 'Bob';
                                insert
                                $new-u isa user, has name 'Charlie', has email 'charlie@typedb.com';
                                $f($u,$new-u) isa friendship;
                                ";
        let response_count = tx.query().insert(match_insert_query)?.count();
        if response_count == 1 {
            tx.commit().resolve()?;
        } else {
            tx.force_close();
        }
    }
}

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the transaction.query.insert() method:
with driver.session(DB_NAME, SessionType.DATA) as session:
    with session.transaction(TransactionType.WRITE) as tx:
        match_insert_query = """
                                match
                                $u isa user, has name "Bob";
                                insert
                                $new-u isa user, has name "Charlie", has email "charlie@typedb.com";
                                $f($u,$new-u) isa friendship;
                                """
        response = list(tx.query.insert(match_insert_query))
        if len(response) == 1:
            tx.commit()
        else:
            tx.close()

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the transaction.query.insert() method:
try {
    session = await driver.session(DB_NAME, SessionType.DATA);
    try {
        tx = await session.transaction(TransactionType.WRITE);
        const match_insert_query = `
                            match
                            $u isa user, has name "Bob";
                            insert
                            $new-u isa user, has name "Charlie", has email "charlie@typedb.com";
                            $f($u,$new-u) isa friendship;
                            `;
        let response = await tx.query.insert(match_insert_query).collect();
        if (response.length == 1) {
            await tx.commit();
        }
        else {await tx.close();}
    }
    finally {if (tx.isOpen()) {await tx.close()};}
}
finally {await session?.close();}

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the transaction.query().insert() method:
try (TypeDBSession session = driver.session(DB_NAME, TypeDBSession.Type.DATA)) {
    try (TypeDBTransaction tx = session.transaction(TypeDBTransaction.Type.WRITE)) {
        String matchInsertQuery = """
                                match
                                $u isa user, has name "Bob";
                                insert
                                $new-u isa user, has name "Charlie", has email "charlie@typedb.com";
                                $f($u,$new-u) isa friendship;
                                """;
        long response_count = tx.query().insert(matchInsertQuery).count();
        if (response_count == 1) {
            tx.commit();
        } else {
            tx.close();
        }
    }
}

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the `transaction.query.insert()` method:
using (ITypeDBSession session = driver.Session(DB_NAME, SessionType.Data)) {
    using (ITypeDBTransaction tx = session.Transaction(TransactionType.Write)) {
        string match_insert_query = @"
                                    match
                                    $u isa user, has name 'Bob';
                                    insert
                                    $new-u isa user, has name 'Charlie', has email 'charlie@typedb.com';
                                    $f($u,$new-u) isa friendship;";
        List<IConceptMap> response = tx.Query.Insert(match_insert_query).ToList();
        if (response.Count == 1) {
            tx.Commit();
        } else {
            tx.Close();
        }
    }
}

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the `transaction.query.insert()` method:
TypeDB::Options options;
TypeDB::Session session = driver.session(DB_NAME, TypeDB::SessionType::DATA, options);
{
    TypeDB::Transaction tx = session.transaction(TypeDB::TransactionType::WRITE, options);
    std::string matchInsertQuery = R"(
                                    match
                                    $u isa user, has name "Bob";
                                    insert
                                    $new-u isa user, has name "Charlie", has email "charlie@typedb.com";
                                    $f($u,$new-u) isa friendship;
                                    )";
    TypeDB::ConceptMapIterable result = tx.query.insert(matchInsertQuery);
    int16_t i = 0;
    for (TypeDB::ConceptMap& element : result) { i+=1; }
    if (i == 1) {
        tx.commit();
    } else {
        tx.close();
    }
}

Follow the connection guide to connect the driver to a TypeDB server.

Open a data session to the selected database, open a write transaction, and use the `query_insert()` function:
Options* opts = options_new();
session = session_new(databaseManager, DB_NAME, Data, opts);
tx = transaction_new(session, Write, opts);
if ((tx == NULL) || FAILED()) {
    handle_error("Transaction failed to start.");
    goto cleanup;
}
char query[512];
snprintf(query, sizeof(query), "match $u isa user, has name 'Bob'; insert $new-u isa user, has name 'Charlie', has email 'charlie@typedb.com'; $f($u,$new-u) isa friendship;");
ConceptMapIterator* insertResult = query_insert(tx, query, opts);
if (FAILED()) {
    handle_error("Query execution failed.");
    goto cleanup;
}
ConceptMap* insertedCM = NULL;
int16_t counter = 0;
while ((insertedCM = concept_map_iterator_next(insertResult)) != NULL) {
    counter++;
}
if ((counter == 1) || FAILED()) void_promise_resolve(transaction_commit(tx));
else {
    handle_error("Transaction commit failed.");
    goto cleanup;
}
session_close(session);

Estimation with a read query

You can estimate the number of inserts made by an Insert query with a match clause by running a preliminary Fetch or Get query with the same match clause in the same transaction. Read queries can be used in a write transaction, and write transactions are snapshoted. Snapshot isolation prevents other transactions from influencing the results.

The most direct approach is to send an aggregated Get query to count the number of matches.

Checking the number of matched results
match $bob isa user, has email "bob@typedb.com";
get; count;

The response should be a single number.

Learn more

More about an Insert query

Learn more about Insert queries in TypeQL: syntax, behavior, and query examples.

Learn how to delete data from a database.

Check out the Writing data section of TypeDB Academy.