Officially out now: The TypeDB 3.0 Roadmap >>

Inference

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

Understanding inference

Rule-based inference can derive new facts from matching patterns in the existing data. It can be used in read transactions only, so no new facts get to be persisted in the database.

How to define a rule

Before you begin, make sure you followed instructions from the Get query page. Inference uses rules defined in the schema of a database. Since our schema from the Define query page has no rules in it, let’s add a new rule to the schema first:

Simple rule example
rule users:
when {
    $u isa user;
} then {
    $u has name "User";
};

Add the define keyword at the beginning and send it as a Define query. See How to send a Define query for exact instructions.

How to send a query with inference

Inference can be enabled as a transaction option for any read transaction.

The easiest way to send a read query with inference 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 read transaction types.

  3. Enable the inference transaction option, by toggling on the infer button.

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

    TypeQL Fetch query
    match
    $u isa user;
    fetch
    $u: name;
  5. Run the query by clicking the studio run Run Query button.

  1. Open a data session and read transaction to the selected database (e.g., sample_db) with the infer transaction option enabled:

    transaction sample_db data read --infer true
  2. Send the Fetch query:

    match
    $u isa user;
    fetch
    $u: name;

    Push Enter twice to send the query.

  3. Close the transaction:

    close

The resulted Log output should look like this:

Results example
{
    "u": {
        "name": [
            { "value": "Alice", "type": { "label": "name", "root": "attribute", "value_type": "string" } },
            { "value": "User", "type": { "label": "name", "root": "attribute", "value_type": "string" } }
        ],
        "type": { "label": "user", "root": "entity" }
    }
}
{
    "u": {
        "name": [
            { "value": "Bob", "type": { "label": "name", "root": "attribute", "value_type": "string" } },
            { "value": "User", "type": { "label": "name", "root": "attribute", "value_type": "string" } }
        ],
        "type": { "label": "user", "root": "entity" }
    }
}
{
    "u": {
        "name": [
            { "value": "Charlie", "type": { "label": "name", "root": "attribute", "value_type": "string" } },
            { "value": "User", "type": { "label": "name", "root": "attribute", "value_type": "string" } }
        ],
        "type": { "label": "user", "root": "entity" }
    }
}

To send a fetch query with inference 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 read transaction, and use the transaction.query().fetch() or transaction.query().get() method to retrieve data with inference:
let databases = DatabaseManager::new(driver);
let db = databases.get(DB_NAME)?;
let options = Options::new().infer(true);
{
    let session = Session::new(db, SessionType::Data)?;
    {
        let tx = session.transaction_with_options(TransactionType::Read, options)?;
        let fetch_query = "
                            match
                            $u isa user;
                            fetch
                            $u: name, email;
                            ";
        let response = tx.query().fetch(fetch_query)?;
        for (i, json) in response.enumerate() {
            println!("User #{}: {}", (i + 1).to_string(), json.unwrap().to_string())
        }
    }
}

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

Open a read transaction, and use the transaction.query.fetch() or transaction.query.get() method to retrieve data with inference:
with driver.session(DB_NAME, SessionType.DATA) as session:
    with session.transaction(TransactionType.READ, TypeDBOptions(infer=True)) as tx:
        fetch_query = """
                        match
                        $u isa user;
                        fetch
                        $u: name, email;
                        """
        response = tx.query.fetch(fetch_query)
        for i, JSON in enumerate(response, start=1):
            print(f"User #{i}: {JSON}")

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

Open a read transaction, and use the transaction.query.fetch() or transaction.query.get() method to retrieve data with inference:
try {
    session = await driver.session(DB_NAME, SessionType.DATA);
    try {
        let options = new TypeDBOptions();
        options.infer = true;
        tx = await session.transaction(TransactionType.READ, options);
        const fetch_query = `
                            match
                            $u isa user;
                            fetch
                            $u: name, email;
                            `;
        let response = await tx.query.fetch(fetch_query).collect();
        for(let i = 0; i < response.length; i++) {
            console.log("User #" + (i + 1) + ": " + JSON.stringify(response[i], null, 4));
        }
    }
    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 read transaction, and use the transaction.query().fetch() or transaction.query().get() method to retrieve data with inference:
try (TypeDBSession session = driver.session(DB_NAME, TypeDBSession.Type.DATA)) {
    TypeDBOptions options = new TypeDBOptions().infer(true);
    try (TypeDBTransaction tx = session.transaction(TypeDBTransaction.Type.READ, options)) {
        String fetchQuery = """
                            match
                            $u isa user;
                            fetch
                            $u: name, email;
                            """;
        int[] ctr = new int[1];
        tx.query().fetch(fetchQuery).forEach(result -> System.out.println("Email #" + (++ctr[0]) + ": " + result.toString()));
    }
}

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

Open a read transaction, and use the transaction.Query.Fetch() or transaction.query.get() method to retrieve data with inference:
using (ITypeDBSession session = driver.Session(DB_NAME, SessionType.Data)) {
    using (ITypeDBTransaction tx = session.Transaction(TransactionType.Read, options.Infer(true))) {
        string fetch_query = @"
                                match
                                $u isa user;
                                fetch
                                $u: name, email;";
        List<JObject> response = tx.Query.Fetch(fetch_query).ToList();
        foreach (JObject answer in response) {
            Console.WriteLine("User: " + answer.ToString());
        }
    }
}

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

Open a read transaction, and use the transaction.query.fetch() or transaction.query.get() method to retrieve data with inference:
TypeDB::Options inferOptions;
inferOptions.infer(true);
TypeDB::Session session2 = driver.session(DB_NAME, TypeDB::SessionType::DATA, inferOptions);
{
    TypeDB::Transaction tx2 = session.transaction(TypeDB::TransactionType::READ, inferOptions);
    std::string fetchQuery = R"(
                                match
                                $u isa user;
                                fetch
                                $u: name, email;
                                )";
    TypeDB::JSONIterable results = tx2.query.fetch(fetchQuery);
    std::vector<TypeDB::JSON> fetchResult;
    for (TypeDB::JSON& result : results) {
        fetchResult.push_back(result);
    }
}

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

Open a read transaction, and use the query_fetch() or query_get() method to retrieve data with inference:
session = session_new(databaseManager, DB_NAME, Data, opts);
Options* optsInfer = options_new();
options_set_infer(optsInfer, true);
tx = transaction_new(session, Read, optsInfer);
if ((tx == NULL) || FAILED()) {
    handle_error("Transaction failed to start.");
    goto cleanup;
}
char queryInfer[512];
snprintf(queryInfer, sizeof(queryInfer), "match $u isa user; fetch $u: name, email;");
StringIterator* users = query_fetch(tx, queryInfer, opts);
if (FAILED()) {
    handle_error("Query execution failed.");
    goto cleanup;
}
char *userJSON;
while ((userJSON = string_iterator_next(users)) != NULL) {
    printf("%s %s\n", "User:", userJSON);
}
transaction_close(tx);
session_close(session);
options_drop(optsInfer);

Learn more

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

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

Check out the Using inference section of TypeDB Academy.