WOQL Basics — Pattern Matching and Graph Traversal

Open inAnthropic

WOQL (Web Object Query Language) is TerminusDB's Datalog-based query language. It finds patterns across documents and their relationships by declaring what you want — not how to get it. Unlike SQL, WOQL traverses document links natively without JOINs. Unlike GraphQL (which TerminusDB also supports), WOQL handles complex pattern matching, recursive traversal, aggregation, and data transformation in a single composable query.

Not sure which query interface to use? See Choosing a Query Interface for a comparison of WOQL, GraphQL, and the HTTP Document API.

Prerequisites This page uses the Star Wars dataset for examples. Clone it from the public templates server or follow the main quickstart first.

WOQL query playground in the TerminusDB dashboard

Your first WOQL query

WOQL queries are composed of variables, triple patterns, and combinators. Let's start with a simple query that looks at one field.

We need to describe which variables we want to use, and we do that with Vars.

Next we add the limit word, to limit to 10 entries.

Then we complete the query with a triple word, using the source variable, the label field, and the destination variable.

Example: JavaScript
let v = Vars("source", "destination");
limit(10).triple(v.source, 'label', v.destination)

The results will come back in a table below in the UI. In the client it will return as a list of JSON objects, having each of the variables described in Vars bound.

The destination variable is filled with elements of type string, because label always terminates in a string. However we can also add other fields to our object, to search for more information by chaining triple together.

Example: JavaScript
let v = Vars("person", "eyes", "name");
limit(5)
  .triple(v.person, 'label', v.name)
  .triple(v.person, 'eye_color', v.eyes)

This query results in the following:

NameEyesPerson
Luke SkywalkerbluePeople/1
Obi-Wan Kenobiblue-grayPeople/10
Anakin SkywalkerbluePeople/11
Wilhuff TarkinbluePeople/12
ChewbaccabluePeople/13

and

The . syntax is actually introducing an implicit and between triple words. We can rewrite our query above as:

Example: JavaScript
let v = Vars("person", "eyes", "name");
limit(5)
  .and(triple(v.person, 'label', v.name),
       triple(v.person, 'eye_color', v.eyes))

select

Since we probably do not really need the person variable, as it is an id, and we are just using it to make sure we are talking about the same person in both triples, we can use select to remove it.

Example: JavaScript
let v = Vars("person", "eyes", "name");
limit(5)
  .select(v.name, v.eyes)
  .and(triple(v.person, 'label', v.name),
       triple(v.person, 'eye_color', v.eyes))

Now we get back the table with the person column removed.

Next steps

Was this helpful?