Cypher Query Examples
Practical Cypher queries for the fXYZ Knowledge Graph with FIBO Party-Role-Context patterns
Cypher Query Examples
Practical queries for interacting with the fXYZ Knowledge Graph using Neo4j's Cypher language. These examples demonstrate the FIBO Party-Role-Context model in action.
Live Explorer: Access the Cypher Explorer at app.fxyz.network/network/cypher to run these queries interactively.
FIBO Hierarchy Queries
Agent to Party Hierarchy
The FIBO model uses an inheritance hierarchy: Agent > Party > Person | Organization
// Find all agents and their types
MATCH (a:Agent)
RETURN a.id, a.name, labels(a) as types, a.active
ORDER BY a.createdAt DESC
LIMIT 20Person with Party Labels
// Find members (Person nodes that are also Party and Agent)
MATCH (p:Person:Party:Agent)
WHERE p.active = true
RETURN p.id, p.name, p.email, p.did
ORDER BY p.nameOrganizations and Business Entities
// Find legal entities with their jurisdiction
MATCH (o:Organization:Party)
RETURN o.id, o.name, o.jurisdiction, o.entityType, o.ein
ORDER BY o.nameParty-Role-Context Queries
Find Member Personas
A persona is the materialized combination of Party + Role + Context:
// Get all personas for a specific member
MATCH (p:Person {email: $email})
OPTIONAL MATCH (p)-[:HAS_PERSONA]->(persona:Persona)
OPTIONAL MATCH (persona)-[:PLAYS]->(role:Role)
OPTIONAL MATCH (persona)-[:IN_CONTEXT]->(ctx:Context)
RETURN
p.name as member,
persona.displayName as persona,
role.name as role,
ctx.name as context,
persona.active as activeCreate a New Persona
// Create persona for member in a specific context
MATCH (p:Person {id: $partyId})
MATCH (r:Role {id: $roleId})
MATCH (c:Context {id: $contextId})
CREATE (persona:Persona:PartyRoleContext {
id: randomUUID(),
partyId: $partyId,
roleId: $roleId,
contextId: $contextId,
displayName: $displayName,
active: true,
createdAt: datetime()
})
CREATE (p)-[:HAS_PERSONA]->(persona)
CREATE (persona)-[:PLAYS]->(r)
CREATE (persona)-[:IN_CONTEXT]->(c)
RETURN personaResolve Active Identity
// Find which persona is currently active for a user
MATCH (m:Member {privyUserId: $userId})
OPTIONAL MATCH (m)-[:HAS_PERSONA]->(p:Persona {active: true})
OPTIONAL MATCH (p)-[:PLAYS]->(r:Role)
OPTIONAL MATCH (p)-[:IN_CONTEXT]->(c:Context)
RETURN m, collect(DISTINCT p) as personas,
collect(DISTINCT r) as roles,
collect(DISTINCT c) as contextsCircle & Holacracy Queries
Circle Hierarchy
// Get circle hierarchy with roles
MATCH (c:Circle)
OPTIONAL MATCH (c)-[:CONTAINS_ROLE]->(r:Role)
OPTIONAL MATCH (c)<-[:PARENT_CIRCLE]-(child:Circle)
RETURN c.name as circle,
collect(DISTINCT r.name) as roles,
collect(DISTINCT child.name) as subCircles
ORDER BY c.nameMembers in a Circle
// Find all members of a specific circle
MATCH (c:Circle {name: $circleName})
MATCH (p:Persona)-[:MEMBER_OF]->(c)
MATCH (m:Member)-[:HAS_PERSONA]->(p)
RETURN m.id, m.name, p.displayName as persona, p.activeRole Assignments
// Find who holds which roles in each circle
MATCH (c:Circle)-[:CONTAINS_ROLE]->(r:Role)
OPTIONAL MATCH (p:Persona)-[:PLAYS]->(r)
OPTIONAL MATCH (m:Member)-[:HAS_PERSONA]->(p)
RETURN c.name as circle,
r.name as role,
r.category as category,
collect(m.name) as assigneesFixie (AI Agent) Queries
Delegation Model
Fixies are SoftwareAgent nodes that can only act via delegation from a Party:
// Find all fixies and their delegations
MATCH (f:SoftwareAgent)
OPTIONAL MATCH (p:Party)-[d:DELEGATES]->(f)
RETURN f.id, f.name, f.agentType as tier,
p.name as delegator,
d.scope as delegationScope,
d.expiresAt as expiresMember's Fixies
// Get all fixies owned by a member
MATCH (m:Member {id: $memberId})-[:OWNS]->(f:SoftwareAgent)
RETURN f.id, f.name, f.agentType, f.model, f.createdAt
ORDER BY f.createdAt DESCNetwork Fixies
// Find network-level fixies (not member-owned)
MATCH (f:SoftwareAgent)
WHERE f.ownerType = 'network'
RETURN f.id, f.name, f.agentType, f.purposeFinancial Queries
Member Balances
// Get member financial overview
MATCH (m:Member {id: $memberId})
OPTIONAL MATCH (m)-[:HAS_WALLET]->(w:Wallet)
OPTIONAL MATCH (m)-[:HAS_VOUCHER]->(v:Voucher)
RETURN m.name,
collect(DISTINCT {chain: w.chain, address: w.address}) as wallets,
collect(DISTINCT {code: v.code, amount: v.amount, redeemed: v.redeemed}) as vouchersBridge Customers
// Find members with Bridge.xyz integration
MATCH (m:Member)-[:HAS_BRIDGE_CUSTOMER]->(bc:BridgeCustomer)
RETURN m.id, m.name,
bc.bridgeCustomerId,
bc.kycStatus,
bc.virtualAccountsGraph Analysis
Network Statistics
// Get overall network stats
MATCH (n)
WITH labels(n) as nodeLabels, count(*) as count
UNWIND nodeLabels as label
RETURN label, sum(count) as total
ORDER BY total DESCRelationship Distribution
// Count relationships by type
MATCH ()-[r]->()
RETURN type(r) as relationship, count(*) as count
ORDER BY count DESCConnected Components
// Find isolated members (not in any circle)
MATCH (m:Member)
WHERE NOT (m)-[:HAS_PERSONA]->(:Persona)-[:MEMBER_OF]->(:Circle)
RETURN m.id, m.name, m.emailTime-Based Queries
Recent Activity
// Find recently created personas
MATCH (p:Persona)
WHERE p.createdAt > datetime() - duration('P7D')
MATCH (m:Member)-[:HAS_PERSONA]->(p)
RETURN m.name, p.displayName, p.createdAt
ORDER BY p.createdAt DESCTemporal Relationships
// Find role assignments with validity periods
MATCH (p:Persona)-[plays:PLAYS]->(r:Role)
WHERE plays.validFrom IS NOT NULL
RETURN p.displayName, r.name,
plays.validFrom, plays.validTo, plays.active
ORDER BY plays.validFrom DESCPerformance-Optimized Queries
Using Indexes
// Use composite index for persona resolution
MATCH (prc:PartyRoleContext)
WHERE prc.partyId = $partyId
AND prc.roleId = $roleId
AND prc.contextId = $contextId
RETURN prcBatched Updates
// Batch update persona statuses
UNWIND $personaIds as personaId
MATCH (p:Persona {id: personaId})
SET p.active = false, p.updatedAt = datetime()
RETURN count(p) as updatedQuery Patterns
Pattern: Member with Full Context
// Complete member profile with all relationships
MATCH (m:Member {privyUserId: $userId})
OPTIONAL MATCH (m)-[:HAS_PERSONA]->(persona:Persona)
OPTIONAL MATCH (persona)-[:PLAYS]->(role:Role)
OPTIONAL MATCH (persona)-[:MEMBER_OF]->(circle:Circle)
OPTIONAL MATCH (m)-[:HAS_WALLET]->(wallet:Wallet)
OPTIONAL MATCH (m)-[:OWNS]->(fixie:SoftwareAgent)
RETURN m as member,
collect(DISTINCT persona) as personas,
collect(DISTINCT role) as roles,
collect(DISTINCT circle) as circles,
collect(DISTINCT wallet) as wallets,
collect(DISTINCT fixie) as fixiesPattern: Circle Financial Summary
// Get budget and expense summary for a circle
MATCH (c:Circle {id: $circleId})
OPTIONAL MATCH (c)-[:HAS_BUDGET]->(b:Budget)
OPTIONAL MATCH (c)-[:HAS_EXPENSE]->(e:Expense)
RETURN c.name,
b.totalAmount as budget,
sum(e.amount) as totalExpenses,
b.totalAmount - sum(e.amount) as remainingGraphQL to Cypher Mapping
The GraphQL API translates queries to Cypher. Here's how common operations map:
| GraphQL Query | Cypher Pattern |
|---|---|
me | MATCH (m:Member {privyUserId: $userId}) |
member(id: ID!) | MATCH (m:Member {id: $id}) |
circles | MATCH (c:Circle) RETURN c |
parties(limit: Int) | MATCH (p:Party) RETURN p LIMIT $limit |
Performance Note: Always use indexed properties (id, privyUserId, email) in WHERE clauses for optimal query performance.