subgraph method

RdfGraph subgraph(
  1. RdfSubject root, {
  2. TraversalFilter? filter,
})

Extracts a subgraph starting from a root subject with optional traversal control

This method creates a true graph-theory subgraph by following reachable nodes from the specified root subject. Unlike matching, which performs pattern-based filtering, this method traverses the graph structure by following object references that are IRIs or blank nodes.

Traversal Behavior:

  • Starts from the root subject
  • For each triple where the root is the subject, includes the triple
  • If the object is an IRI or blank node, recursively traverses from that object
  • Includes cycle detection to prevent infinite loops
  • Optional filter callback allows fine-grained control over traversal

Traversal Control: The optional filter callback is invoked for each triple encountered during traversal, allowing you to control which triples are included and whether traversal should continue from their objects.

Parameters:

  • root The subject to start traversal from
  • filter Optional callback to control traversal behavior for each triple

Returns: A new RdfGraph containing all reachable triples from the root subject, filtered according to the traversal decisions.

Example:

// Simple subgraph extraction
final aliceSubgraph = graph.subgraph(alice);

// Controlled traversal - exclude email and don't descend from addresses
final filtered = graph.subgraph(alice, filter: (triple, depth) {
  // Don't include email triples at all
  if (triple.predicate.iri.endsWith('email')) {
    return TraversalDecision.skip;
  }

  // Include address info but don't traverse into address details
  if (triple.predicate.iri.endsWith('hasAddress')) {
    return TraversalDecision.includeButDontDescend;
  }

  // Limit traversal depth
  if (depth > 2) {
    return TraversalDecision.includeButDontDescend;
  }

  return TraversalDecision.include;
});

// List filtering example using skipButDescend
// Extract only list values from RDF lists, skipping structural elements
final listValues = graph.subgraph(listRoot, filter: (triple, depth) {
  // Skip rdf:rest (list structure) but continue following the list
  if (triple.predicate.iri == 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest') {
    return TraversalDecision.skipButDescend;
  }
  // Include rdf:first (actual values) and other content
  return TraversalDecision.include;
});

Implementation

RdfGraph subgraph(RdfSubject root, {TraversalFilter? filter}) {
  final subgraphTriples = _getSubgraphTriples(
    this,
    root,
    filter: filter,
  ).toList();
  return RdfGraph(triples: subgraphTriples, enableIndexing: indexingEnabled);
}