What are Relationships?
Relationships are explicit, typed connections between entities. Unlike implicit associations in text, our relationships are:
- Directional: A
plays_for B (not just “associated”)
- Typed: Specific relationship roles
- Traversable: Build graphs and trace effects
Relationship Structure
{
"role": "plays_for",
"entity": {
"id": "uuid",
"slug": "kansas-city-chiefs",
"displayName": "Kansas City Chiefs",
"entityType": "team"
}
}
Relationship Types
| Relationship | From → To | Description |
|---|
plays_for | person → team | Athlete plays for team |
member_of | person → org | Person belongs to organization |
plays_at | team → place | Team’s home venue |
located_in | place → place | Location hierarchy |
competes_in | team → league | Team’s league membership |
governs | person → place | Politician governs jurisdiction |
founded | person → org | Founder relationship |
ceo_of | person → org | Executive leadership |
Traversing Relationships
Example: Patrick Mahomes
Patrick Mahomes
│
├── plays_for → Kansas City Chiefs
│ │
│ ├── plays_at → Arrowhead Stadium
│ │ │
│ │ └── located_in → Kansas City
│ │
│ └── competes_in → NFL
│
└── [marketExposures] → "Chiefs Super Bowl", "MVP Award"
Getting the Graph
GET /api/entities/patrick-mahomes/graph?depth=2
Response:
{
"success": true,
"graph": {
"nodes": [
{ "id": "patrick-mahomes", "label": "Patrick Mahomes", "type": "person" },
{ "id": "kansas-city-chiefs", "label": "Kansas City Chiefs", "type": "team" },
{ "id": "arrowhead-stadium", "label": "Arrowhead Stadium", "type": "place" },
{ "id": "nfl", "label": "NFL", "type": "league" }
],
"edges": [
{ "source": "patrick-mahomes", "target": "kansas-city-chiefs", "label": "plays_for" },
{ "source": "kansas-city-chiefs", "target": "arrowhead-stadium", "label": "plays_at" },
{ "source": "kansas-city-chiefs", "target": "nfl", "label": "competes_in" }
]
}
}
Second-Order Effects
Relationships let you trace how changes propagate:
Entity attribute changes
Patrick Mahomes: injury_status → “questionable”
Direct market effect
“Chiefs to win Super Bowl” market affected
Related entity effect
Kansas City Chiefs team markets affected
Venue effect
Arrowhead Stadium weather data now relevant to spread
Use Cases
Portfolio Exposure Analysis
// Find all entities connected to a team
const graph = await fetch('/api/entities/kansas-city-chiefs/graph?depth=1');
// Get all unique market exposures across the graph
const allMarkets = new Set();
for (const node of graph.nodes) {
const entity = await fetch(`/api/entities/${node.id}`);
entity.marketExposures.forEach(m => allMarkets.add(m.market.id));
}
Event Impact Tracing
// When a stadium has weather issues, find affected markets
const stadium = await fetch('/api/entities/arrowhead-stadium');
// Get teams that play at this stadium
const teamsPlayingHere = stadium.entity.relationships
.filter(r => r.role === 'home_of')
.map(r => r.entity.slug);
// Get all markets for those teams
for (const teamSlug of teamsPlayingHere) {
const team = await fetch(`/api/entities/${teamSlug}`);
console.log(`Markets affected: ${team.entity.marketExposures.length}`);
}
Conflict of Interest Detection
// Find if two entities are connected
const graph = await fetch('/api/entities/entity-a/graph?depth=3');
const connectedSlugs = graph.nodes.map(n => n.id);
if (connectedSlugs.includes('entity-b')) {
console.log('Entities are connected within 3 degrees');
}
Bidirectional Relationships
Some relationships are inherently bidirectional. When you fetch an entity, you see relationships from that entity. The inverse may appear on the related entity:
| Forward | Inverse |
|---|
plays_for (player → team) | has_player (team → player) |
plays_at (team → venue) | home_of (venue → team) |
located_in (place → place) | contains (place → place) |
The graph endpoint returns all edges regardless of direction, making it ideal for visualization and traversal.