Property Graphs & Knowledge Graphs
Methodology → representation
Graphs are memory with structure — but not all structure is causal.
Teams often say “knowledge graph” when they really mean “a graph database”. The difference matters because governance and meaning live in different layers than traversal and retrieval.
Two graph families (and what each optimizes)¶
Property graph
Purpose: engineering ergonomics and fast traversal.
Data model: nodes/edges with arbitrary key-value properties.
Typical wins: exploration, neighborhood expansion, ranking, path queries.
Knowledge graph
Purpose: semantics, interoperability, and governance.
Data model: typed concepts and relations, explicit meaning, validation rules.
Typical wins: schema discipline, policy enforcement, consistent interpretation.
Hybrid (often best)
Point: not every problem fits one graph style.
Pattern: use a property graph for fast retrieval and workflows, then layer knowledge-graph semantics for meaning, constraints, and audit.
Result: speed without losing correctness when stakes rise.
Diagram: data vs meaning¶
flowchart TB
%% Styles (brModel Standard)
classDef i fill:#D3D3D3,stroke-width:0px,color:#000;
classDef p fill:#B3D9FF,stroke-width:0px,color:#000;
classDef r fill:#FFFFB3,stroke-width:0px,color:#000;
classDef o fill:#C1F0C1,stroke-width:0px,color:#000;
classDef s fill:#FFB3B3,stroke-width:0px,color:#000;
P_PG("🕸️ Property graph (store + traverse)"):::p
P_Ont("📚 Ontology (types + meaning)"):::p
P_Con("🔒 Constraints (SHACL rules)"):::p
R_KG(["Knowledge graph semantics (typed edges + validity)"]):::r
D_Valid{"✅ Valid under rules?"}:::s
O_Q(["✅ Queries you can trust (valid under rules)"]):::o
S_Bad(["🛑 Block or return violations"]):::s
P_PG --> R_KG
P_Ont --> R_KG
P_Con --> R_KG --> D_Valid
D_Valid -->|"Yes"| O_Q
D_Valid -->|"No"| S_Bad
%% Clickable nodes
click P_Con "/methodology/constraints/" "Constraints & SHACL"
click P_PG "/methodology/property-and-knowledge-graphs/" "Property & Knowledge Graphs"
Interpretation: a property graph gives you 🕸️ storage + traversal, but “knowledge” emerges only when you add 📚 meaning and 🔒 constraints. The ✅ valid under rules? gate is what turns fast traversal into ✅ queries you can trust (or 🛑 violations you can fix).
Where graphs help — and where they mislead¶
A graph can store "what is connected" without storing "why it is true".
Causal claims require mechanisms and counterfactual commitments; paths alone are not enough.
Great for
- Navigation: “show me what relates to X”
- Evidence clusters: “what supports this claim”
- Governance: “is this assertion even allowed”
Risky for
- Equating proximity with causality
- Mixing incompatible sources without noticing
- Smuggling policy decisions into “similarity” heuristics
Helps when you need traceability
Graphs shine when each edge is an inspectable claim with provenance. You can ask not only what connects, but which source says so and under what scope.
Misleads when you skip semantics
If relations aren’t typed and validated, traversal blends different meanings into one path. The output looks coherent, but it may be logically invalid or policy-violating.
Helps when the world changes
With versioned sources and constraints, you can detect drift: what changed, which edges became stale, and which decisions must be revalidated after deployment.
Misleads under optimization pressure
When graphs drive ranking or automation, agents learn to game proxies. Without guardrails and counterfactual checks, “best path” becomes a policy choice disguised as retrieval.
Diagram: provenance as a first-class object¶
flowchart TB
%% Styles (brModel Standard)
classDef i fill:#D3D3D3,stroke-width:0px,color:#000;
classDef p fill:#B3D9FF,stroke-width:0px,color:#000;
classDef r fill:#FFFFB3,stroke-width:0px,color:#000;
classDef o fill:#C1F0C1,stroke-width:0px,color:#000;
classDef s fill:#FFB3B3,stroke-width:0px,color:#000;
I_S(["📄 Source document"]):::i
R_V(["⏱️ Version + scope"]):::r
R_F(["🧾 Claim / fact (provenance-first)"]):::r
P_E("🔗 Edge assertion (typed relation)"):::p
P_C("🔒 Constraint validation"):::p
D_OK{"✅ Allowed?"}:::s
O_OK(["✅ Commit + auditable graph state"]):::o
S_NO(["🛑 Block + violation report"]):::i
I_S --> R_V --> R_F --> P_E --> P_C
P_C --> D_OK
D_OK -->|"Yes"| O_OK
D_OK -->|"No"| S_NO
%% Clickable nodes
click P_C "/methodology/constraints/" "Constraints & SHACL"
click P_E "/methodology/core-primitives/" "Core primitives"
Why provenance matters: edges are not “connections” but typed assertions backed by 🧾 claims tied to ⏱️ versions. A ✅ allowed? decision prevents invalid commits and forces explicit 🛑 violation reports when rules fail.
Practical rule¶
- If you need speed and flexible ingestion: start with a property graph.
- If you need governance, auditability, and correctness: add knowledge-graph semantics (types + constraints + provenance).
- If you need “why, not just what”: build causal traversal on top (paths + traces + abstention).