Skip to content

Graph consistency

What this is

Validate relationships across linked entities, not only one node in isolation.

When to use it

Use graph consistency when correctness depends on references and cross-node context:

  • operation <-> equipment tag alignment
  • work-order link completeness
  • cross-model semantic agreement

Industrial examples

  • An operation tag on a work order must also exist on its linked equipment object.
  • If a pump references a parent unit, the parent unit must exist and be in the same site hierarchy.
  • A functional location relation must point to a valid location node, not a missing external reference.

Cross-property / cross-node semantic agreement is typically implemented as sh:sparql constraints over linked nodes.

Related nodes must be auto-loaded

SPARQL that walks a direct relation (for example $this op:equipment ?equipment then properties or rdf:type on ?equipment) only sees neighbours that are already in the validation graph. Forward auto-load requires sh:node on that path; reverse auto-load requires neat:reverseDirectRelation. Raising auto_load_depth alone does not load undeclared targets. See SHACL and CDF Data Models — Auto-load.

Typed edge cardinality (MultiEdgeConnection / EdgeConnection min/max counts) uses a different executor: dqs:edgeExistenceConstraint. Node-only SHACL often cannot see those edges on the node dump. See Edge existence.

Example (SHACL + SPARQL)

@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix op:  <http://purl.org/cognite/my_space/Operation/> .
@prefix eq:  <http://purl.org/cognite/my_space/Equipment/> .

eq:EquipmentStubShape
    a sh:NodeShape ;
    sh:targetClass eq:Equipment ;
    sh:name "Equipment" .

op:OperationTagConsistencyShape
    a sh:NodeShape ;
    sh:targetClass op:Operation ;
    sh:property [
        sh:path op:equipment ;
        sh:node eq:EquipmentStubShape ;  # required so ?equipment is auto-loaded
        sh:sparql [
            sh:message "Operation tag must exist on linked equipment." ;
            sh:select """
                PREFIX op: <http://purl.org/cognite/my_space/Operation/>
                SELECT $this ?opTag WHERE {
                    $this op:tag ?opTag ;
                          op:equipment ?equipment .
                    FILTER NOT EXISTS {
                        ?equipment op:tag ?eqTag .
                        FILTER(?eqTag = ?opTag)
                    }
                }
            """ ;
        ] ;
    ] .

Without sh:node, the same SPARQL often false-fails every populated op:equipment link because the equipment node was never retrieved into the graph.

Previous section

Next section