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:
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:
-
Use a drop-down list in the top toolbar to select a database.
-
Switch to
data
session andread
transaction types. -
Enable the inference transaction option, by toggling on the
infer
button. -
Open a new tab and insert or type in an Insert query, for example:
TypeQL Fetch querymatch $u isa user; fetch $u: name;
-
Run the query by clicking the Run Query button.
-
Open a
data
session andread
transaction to the selected database (e.g.,sample_db
) with theinfer
transaction option enabled:transaction sample_db data read --infer true
-
Send the Fetch query:
match $u isa user; fetch $u: name;
Push Enter twice to send the query.
-
Close the transaction:
close
The resulted Log output should look like this:
{
"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.
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.
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.
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.
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.
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.
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.
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);