RDF List Access Operations

Open inAnthropic

This guide covers operations for reading elements from RDF lists. These operations allow you to inspect list contents without modifying the underlying structure.

What You'll Learn

  • How to read the first element of a list
  • How to iterate through all list elements
  • How to count list elements
  • How to extract slices of lists
  • How to access elements by index (nth0/nth1)

Operations Summary

OperationDescriptionTime Complexity
rdflist_peekGet first elementO(1)
rdflist_memberIterate all elementsO(n)
rdflist_lengthCount elementsO(n)
rdflist_listCollect all elements as arrayO(n)
rdflist_sliceExtract a range of elementsO(n)

rdflist_peek

Gets the first element (head) of an RDF list without removing it, or match it with the value in the variable when using as a match operator.

Syntax

Example: JavaScript
WOQL.lib().rdflist_peek(consSubject, valueVar)

Parameters

ParameterTypeDescription
consSubjectstringThe list head identifier
valueVarstringVariable to bind the first value

Example

Example: JavaScript
const query = WOQL.lib().rdflist_peek(listHead, "v:first_value");
const result = await client.query(query);

const firstValue = result.bindings[0]["first_value"];
console.log(firstValue["@value"]); // "Task A"

Use Cases

  • Preview: Check the first item without consuming it
  • Stack peek: Implement stack-like peek operations
  • Validation: Verify the head element before processing

rdflist_member

Traverses an RDF list and binds each element to a variable through unification. Returns multiple bindings, one for each element. Can be used to both match existing list elements and generate solutions.

Syntax

Example: JavaScript
WOQL.lib().rdflist_member(consSubject, valueVar)

Parameters

ParameterTypeDescription
consSubjectstringThe list head identifier
valueVarstringVariable to bind each element

Example

Example: JavaScript
const query = WOQL.lib().rdflist_member(listHead, "v:value");
const result = await client.query(query);

// Returns multiple bindings
const values = result.bindings.map(b => {
  const val = b["value"] || b["v:value"];
  return val?.["@value"] || val;
});

console.log(values); // ["Task A", "Task B", "Task C"]

Use Cases

  • Iteration: Process each element in the list
  • Search: Find elements matching criteria
  • Aggregation: Collect values for further processing

Combining with Other Queries

Example: JavaScript
// Find all tasks with high priority
const query = WOQL.and(
  WOQL.lib().rdflist_member(taskListHead, "v:task_id"),
  WOQL.triple("v:task_id", "priority", "v:priority"),
  WOQL.greater("v:priority", 5)
);

rdflist_length

Counts the number of elements in an RDF list, or match that the number of elements match a variable.

Syntax

Example: JavaScript
WOQL.lib().rdflist_length(consSubject, lengthVar)

Parameters

ParameterTypeDescription
consSubjectstringThe list head identifier
lengthVarstringVariable to bind the count

Example

Example: JavaScript
const query = WOQL.lib().rdflist_length(listHead, "v:count");
const result = await client.query(query);

const length = parseInt(result.bindings[0]["count"]["@value"]);
console.log(`List has ${length} elements`);

Use Cases

  • Validation: Check list size constraints
  • Pagination: Calculate total pages
  • Capacity checks: Verify list doesn't exceed limits

rdflist_list

Collects all elements from an RDF list into a single array in one binding. Can also be used to verify that an RDF list matches a given array.

Syntax

Example: JavaScript
WOQL.lib().rdflist_list(consSubject, listVar)

Parameters

ParameterTypeDescription
consSubjectstringThe list head identifier
listVarstringVariable to bind the collected array

Example

Example: JavaScript
const query = WOQL.lib().rdflist_list(listHead, "v:all_items");
const result = await client.query(query);

const items = result.bindings[0]["all_items"];
console.log(items); // [{@value: "A"}, {@value: "B"}, {@value: "C"}]

// Extract values
const values = items.map(item => item?.["@value"] || item);
console.log(values); // ["A", "B", "C"]

Use Cases

  • Export: Get all list items in one result
  • Comparison: Compare entire lists
  • Serialization: Convert list to JSON array

Difference from rdflist_member

OperationReturnsBindings
rdflist_memberOne element per bindingMultiple bindings
rdflist_listAll elements as arraySingle binding

rdflist_slice

Extracts a range of elements from an RDF list. Uses 0-based indexing and an exclusive end. Think of the positions to match to be the positions "between" the elements. 0 is before the first element, 1 is after the first element, etc. Thus, to slice the first element, slice between 0 and 1.

Syntax

Example: JavaScript
WOQL.lib().rdflist_slice(consSubject, start, end, resultVar)

Parameters

ParameterTypeDescription
consSubjectstringThe list head identifier
startnumberStart index (0-based, inclusive)
endnumberEnd index (exclusive)
resultVarstringVariable to bind the slice array

Examples

Example: JavaScript
// List: [A, B, C, D]

// Get first two elements: slice(0, 2) → [A, B]
const first2 = WOQL.lib().rdflist_slice(listHead, 0, 2, "v:result");

// Get middle elements: slice(1, 3) → [B, C]
const middle = WOQL.lib().rdflist_slice(listHead, 1, 3, "v:result");

// Get last two elements: slice(2, 4) → [C, D]
const last2 = WOQL.lib().rdflist_slice(listHead, 2, 4, "v:result");

// Single element: slice(1, 2) → [B]
const single = WOQL.lib().rdflist_slice(listHead, 1, 2, "v:result");

// Empty slice when start >= end: slice(2, 2) → []
const empty = WOQL.lib().rdflist_slice(listHead, 2, 2, "v:result");

Use Cases

  • Pagination: Get a page of results
  • Preview: Show first N items
  • Windowing: Process data in chunks

Accessing Elements by Index

You can use slice instead of nth0 or nth1 operations for single items.

Using Slice for Index Access

Example: JavaScript
// Get element at index 2 (0-based)
const getAt2 = WOQL.lib().rdflist_slice(listHead, 2, 3, "v:element");
const result = await client.query(getAt2);
const element = result.bindings[0]["element"][0]; // First item of single-element array

Using Path Queries instead, for manual parsing

Notice that WOQL.path() uses regex style matching (inclusive), whereas slice uses exclusive matching, like in Javascript.

Example: JavaScript
// Access elements by path traversal
// Path {n,n} traverses exactly n rdf:rest links
const pathQuery = WOQL.and(
  WOQL.path(listHead, "rdf:rest{2,2}", "v:cell"),  // Skip 2 cells
  WOQL.triple("v:cell", "rdf:first", "v:value")    // Get value
);

Zero-Based vs One-Based Indexing

  • 0-based (nth0): First element is at index 0
  • 1-based (nth1): First element is at index 1

Use slice with appropriate indices:

  • nth0(2) = slice(2, 3)[0]
  • nth1(2) = slice(1, 2)[0]

Complete Example: List Analysis

List head in the example below is the object of a triple from a list. A list defined on a document/record in TerminusDB will have a triple such as triple("v:docId", "list", "v:listHeadId"). The listHeadId would be what is called a Cons, an rdf:List "construct" that is the start of a list.

Example: JavaScript
import { WOQLClient, WOQL } from "@terminusdb/terminusdb-client";

async function analyzeList(client, listHead) {
  // Get list length
  const lengthQuery = WOQL.lib().rdflist_length(listHead, "v:len");
  const lengthResult = await client.query(lengthQuery);
  const length = parseInt(lengthResult.bindings[0]["len"]["@value"]);
  console.log(`List length: ${length}`);
  
  if (length === 0) {
    console.log("List is empty");
    return;
  }
  
  // Get first element
  const peekQuery = WOQL.lib().rdflist_peek(listHead, "v:first");
  const peekResult = await client.query(peekQuery);
  console.log(`First element: ${peekResult.bindings[0]["first"]["@value"]}`);
  
  // Get all elements
  const listQuery = WOQL.lib().rdflist_list(listHead, "v:all");
  const listResult = await client.query(listQuery);
  const allItems = listResult.bindings[0]["all"];
  console.log("All elements:", allItems.map(i => i["@value"]));
  
  // Get first half
  const halfLength = Math.ceil(length / 2);
  const sliceQuery = WOQL.lib().rdflist_slice(listHead, 0, halfLength, "v:half");
  const sliceResult = await client.query(sliceQuery);
  const firstHalf = sliceResult.bindings[0]["half"];
  console.log("First half:", firstHalf.map(i => i["@value"]));
}

Working with Document References in Lists

Example: JavaScript
// Create tasks
await client.addDocument([
  { "@type": "Task", "@id": "Task/1", title: "Fix bug", priority: 1 },
  { "@type": "Task", "@id": "Task/2", title: "Update docs", priority: 2 }
]);

// Read task details from list
const detailsQuery = WOQL.and(
  WOQL.lib().rdflist_member(taskListHead, "v:task_id"),
  WOQL.triple("v:task_id", "title", "v:title"),
  WOQL.triple("v:task_id", "priority", "v:priority")
);

const details = await client.query(detailsQuery);
// Returns: [{task_id: "Task/1", title: "Fix bug", priority: 1}, ...]

Read More

Was this helpful?