Officially out now: The TypeDB 3.0 Roadmap >>

Update query

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

Understanding Update queries

An Update query is used to update data in a TypeDB database by matching existing data, deleting some of it, and then inserting some other data instead. A delete and insert clauses are executed once per every result matched by the match clause of the same Update query. For a detailed explanation of the query see the Update query page.

Sending Update queries

Before you start, make sure you followed instructions from the Delete query page. The easiest way to send an Update 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 Update query, for example:

    TypeQL Update query
    match
    $u isa user, has name 'Charlie', has email $e;
    delete
    $u has $e;
    insert
    $u has email 'charles@typedb.com';
  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 Update query:

    match
    $u isa user, has name 'Charlie', has email $e;
    delete
    $u has $e;
    insert
    $u has email 'charles@typedb.com';

    Push Enter twice to send the query.

  3. Commit the changes:

    commit

To send an Update 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().update() 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 update_query = "
                            match
                            $u isa user, has name 'Charlie', has email $e;
                            delete
                            $u has $e;
                            insert
                            $u has email 'charles@typedb.com';
                            ";
        let response_count = tx.query().update(update_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.update()` method:
with driver.session(DB_NAME, SessionType.DATA) as session:
    with session.transaction(TransactionType.WRITE) as tx:
        update_query = """
                        match
                        $u isa user, has name "Charlie", has email $e;
                        delete
                        $u has $e;
                        insert
                        $u has email "charles@typedb.com";
                        """
        response = list(tx.query.update(update_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.update()` method:
try {
    session = await driver.session(DB_NAME, SessionType.DATA);
    try {
        tx = await session.transaction(TransactionType.WRITE);
        const update_query = `
                            match
                            $u isa user, has name "Charlie", has email $e;
                            delete
                            $u has $e;
                            insert
                            $u has email "charles@typedb.com";
                            `;
        let response = await tx.query.update(update_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().update()` method:
try (TypeDBSession session = driver.session(DB_NAME, TypeDBSession.Type.DATA)) {
    try (TypeDBTransaction tx = session.transaction(TypeDBTransaction.Type.WRITE)) {
        String updateQuery = """
                            match
                            $u isa user, has name "Charlie", has email $e;
                            delete
                            $u has $e;
                            insert
                            $u has email "charles@typedb.com";
                            """;
        long response_count = tx.query().update(updateQuery).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.Update()` method:
using (ITypeDBSession session = driver.Session(DB_NAME, SessionType.Data)) {
    using (ITypeDBTransaction tx = session.Transaction(TransactionType.Write)) {
        string update_query = @"
                        match
                        $u isa user, has name 'Charlie', has email $e;
                        delete
                        $u has $e;
                        insert
                        $u has email 'charles@typedb.com';";
        List<IConceptMap> response = tx.Query.Update(update_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.update()` 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 updateQuery = R"(
                                match
                                $u isa user, has name "Charlie", has email $e;
                                delete
                                $u has $e;
                                insert
                                $u has email "charles@typedb.com";
                                )";
    TypeDB::ConceptMapIterable result = tx.query.update(updateQuery);
    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_update()` 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 'Charlie', has email $e; delete $u has $e; insert $u has email 'charles@typedb.com';");
ConceptMapIterator* insertResult = query_update(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);

Response interpretation

An Update query returns all concepts that got inserted into the database.

Both delete and insert clauses are executed once per every result matched by the match clause of the same Update query.

The delete clause of an Update query is executed the same number of times as the insert clause, but if a concept specified for deletion is no longer present in a database for any reason, that would not produce an error. The query will continue its execution.

You can check the response of an Update query to see what was inserted. The response is a Stream/Iterator with a ConceptMap object for every execution of the insert clause. A ConceptMap object maps every variable from a query to a particular concept in a database.

Check the response

The easiest way to check the response for the query is to use a TypeDB client: Studio or Console. For more information on how to send the above Update query, see above the Sending Update queries section.

Both Studio and Console should produce similar results:

{
    $e the-bob@typedb.com isa email;
    $u iid 0x826e80018000000000000001 isa user;
    $_0 the-bob@typedb.com isa email;
}

To process the response of an Update query programmatically, we need to collect the response and iterate through it. See the code to check the response for the number of inserts above, in the Sending Update queries section.

The example above checks the response of an Update query and commits the changes only if the number of inserts is equal to the expected number (1). Otherwise, it closes the transaction without committing the changes.

Estimation with a read query

You can estimate the number of inserts in an Update query with a match clause by running a dedicated 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, providing isolation from changes made by other transactions.

To estimate the number of inserts in an Update query, use the same write transaction to send any type of a read query with the same match clause, as the Update query. The most direct approach is to send an aggregated Get query to count the number of matches.

Checking the number of matched results
match
$u isa user, has name "Bob", has email $e;
get; count;

The response is a single number. The aggregated number of matched results is equal to the number of times the delete and insert clauses of a Delete query with the same match clause in the same write transaction will be executed.

Learn more

More about an Update query

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

Learn how to read data from a TypeDB database.

Check out the Writing data section of TypeDB Academy.