Skip to content

16.2 Introspection — what a step needs and makes

In a view or rule body Read as
CALL ai.fromText(…, '<pattern>') makes the pattern’s projected nodes and relationships, and its resolved world-type edges
CREATE / MERGE of a projected label, or of a relationship declared on a projected type makes it
MATCH, OPTIONAL MATCH, EXISTS {} or NOT EXISTS {} over a projected label or relationship needs it
MATCH over a world label nothing — the world provides it
a derives: label (§13), a view’s outputLabel a named output
$x read into ai.fromText an input: text
$x keyed on a spine L ({accountKey: $x}) or read into canonicalize(…, 'L') (§5.4.4) an input: an identity of L

Facts are named node:Issue and edge:Attendee-RAISED->Issue; a path pattern is the set of its edges. The goal is read by the same rules: every fact it reads is a fact the plan must make.

  • NOT EXISTS is a need. The goal above reads TRACKED_BY only to test its absence. Counted only positively, a plan that skipped the step making TRACKED_BY would type-check, and every issue would come back “untracked” because the edge could never exist.
  • World labels are free. The world is always there; a step is never chosen to provide one.
  • Types say what, not which. Two views that both return CustomerAccount rows — “at risk”, “owes money” — are identical by type, and a planner choosing between them by type would pick wrongly. So planning is over named facts only. A view that returns only world labels — including one whose outputLabel is a type the world already declares — makes no fact: it is a question, not a step.
  • What cannot be read is left out, never guessed. A body the pass cannot type, a view with a parameter that is neither text nor identity and has neither a default nor an input of its name, and a rule set with a param it does not default (which never fires on its own, §13.1) are each left out of planning with a diagnostic naming why.
  • A goal view is never a step (§16.10).