Merged 'Author' nodes into 'NostrUser' for unified identity tracking and social graph representation. Introduced migrations framework to handle schema changes, including retroactive updates for existing relationships and constraints. Updated tests, schema definitions, and documentation to reflect these changes.
6.6 KiB
Neo4j Database Backend
A graph database backend implementation for the ORLY Nostr relay using Neo4j.
Quick Start
1. Start Neo4j
docker run -d --name neo4j \
-p 7474:7474 -p 7687:7687 \
-e NEO4J_AUTH=neo4j/password \
neo4j:5.15
2. Configure Environment
All Neo4j configuration is defined in app/config/config.go and visible via ./orly help:
export ORLY_DB_TYPE=neo4j
export ORLY_NEO4J_URI=bolt://localhost:7687
export ORLY_NEO4J_USER=neo4j
export ORLY_NEO4J_PASSWORD=password
Note: Configuration is centralized in
app/config/config.go. Do not useos.Getenv()directly in package code - all environment variables should be passed via thedatabase.DatabaseConfigstruct.
3. Run ORLY
./orly
Features
- Graph-Native Storage: Events, authors, and tags stored as nodes and relationships
- Efficient Queries: Leverages Neo4j's native graph traversal for tag and social graph queries
- Cypher Query Language: Powerful, expressive query language for complex filters
- Automatic Indexing: Unique constraints and indexes for optimal performance
- Relationship Queries: Native support for event references, mentions, and tags
- Web of Trust (WoT) Extensions: Optional support for trust metrics, social graph analysis, and content filtering (see WOT_SPEC.md)
Architecture
See docs/NEO4J_BACKEND.md for comprehensive documentation on:
- Graph schema design
- How Nostr REQ messages are implemented in Cypher
- Performance tuning
- Development guide
- Comparison with other backends
Web of Trust (WoT) Extensions
This package includes schema support for Web of Trust trust metrics computation:
-
WOT_SPEC.md - Complete specification of the WoT data model, based on the Brainstorm prototype
- NostrUser nodes with trust metrics (influence, PageRank, verified counts)
- NostrUserWotMetricsCard nodes for personalized multi-tenant metrics
- Social graph relationships (FOLLOWS, MUTES, REPORTS)
- Cypher schema definitions and example queries
-
ADDITIONAL_REQUIREMENTS.md - Implementation requirements and missing details
- Algorithm implementations (GrapeRank, Personalized PageRank)
- Event processing logic for kinds 0, 3, 1984, 10000
- Multi-tenant architecture and configuration
- Performance considerations and deployment modes
Note: The WoT schema is applied automatically but WoT features are not yet fully implemented. See ADDITIONAL_REQUIREMENTS.md for the roadmap.
File Structure
Core Implementation
neo4j.go- Main database implementationschema.go- Graph schema and index definitions (includes WoT extensions)query-events.go- REQ filter to Cypher translationsave-event.go- Event storage with relationship creationfetch-event.go- Event retrieval by serial/IDserial.go- Serial number managementmarkers.go- Metadata key-value storageidentity.go- Relay identity managementdelete.go- Event deletion (NIP-09)subscriptions.go- Subscription managementnip43.go- Invite-based ACL (NIP-43)import-export.go- Event import/exportlogger.go- Logging infrastructure
Documentation
README.md- This fileWOT_SPEC.md- Web of Trust data model specificationADDITIONAL_REQUIREMENTS.md- WoT implementation requirements and gapsEVENT_PROCESSING_SPEC.md- Event-driven vertex management specificationIMPLEMENTATION_SUMMARY.md- Implementation overview and statusTESTING.md- Test guide and troubleshootingThe Brainstorm prototype_ Neo4j Data Model.html- Original Brainstorm specification document
Tests
social-event-processor_test.go- Comprehensive tests for kinds 0, 3, 1984, 10000
Testing
Quick Start
# Start Neo4j using docker-compose
cd pkg/neo4j
docker-compose up -d
# Wait for Neo4j to be ready (~30 seconds)
docker-compose logs -f neo4j # Look for "Started."
# Set Neo4j connection
export ORLY_NEO4J_URI="bolt://localhost:7687"
export ORLY_NEO4J_USER="neo4j"
export ORLY_NEO4J_PASSWORD="testpass123"
# Run all tests
go test -v
# Run social event processor tests
go test -v -run TestSocialEventProcessor
# Cleanup
docker-compose down -v
Test Coverage
The social-event-processor_test.go file contains comprehensive tests for:
- Kind 0: Profile metadata processing
- Kind 3: Contact list creation and diff-based updates
- Kind 1984: Report processing (multiple reports, different types)
- Kind 10000: Mute list processing
- Event traceability: Verifies all relationships link to source events
- Graph state: Validates final graph matches expected state
- Helper functions: Unit tests for diff computation and p-tag extraction
See TESTING.md for detailed test documentation, troubleshooting, and how to view the graph in Neo4j Browser.
Viewing Test Results
After running tests, explore the graph at http://localhost:7474:
// View all social relationships
MATCH path = (u1:NostrUser)-[r:FOLLOWS|MUTES|REPORTS]->(u2:NostrUser)
RETURN path
// View event processing history
MATCH (evt:ProcessedSocialEvent)
RETURN evt ORDER BY evt.created_at
Example Cypher Queries
Find all events by an author
MATCH (e:Event {pubkey: "abc123..."})
RETURN e
ORDER BY e.created_at DESC
Find events with specific tags
MATCH (e:Event)-[:TAGGED_WITH]->(t:Tag {type: "t", value: "bitcoin"})
RETURN e
Social graph query
MATCH (author:NostrUser {pubkey: "abc123..."})
<-[:AUTHORED_BY]-(e:Event)
-[:MENTIONS]->(mentioned:NostrUser)
RETURN author, e, mentioned
Performance Tips
- Use Limits: Always include LIMIT in queries
- Index Usage: Ensure queries use indexed properties (id, kind, created_at)
- Parameterize: Use parameterized queries to enable query plan caching
- Monitor: Use
EXPLAINandPROFILEto analyze query performance
Limitations
- Requires external Neo4j database (not embedded)
- Higher memory usage compared to Badger
- Metadata still uses Badger (markers, subscriptions)
- More complex deployment than single-binary solutions
Why Neo4j for Nostr?
Nostr is inherently a social graph with heavy relationship queries:
- Event references (e-tags) → Graph edges
- Author mentions (p-tags) → Graph edges
- Follow relationships → Graph structure
- Thread traversal → Path queries
Neo4j excels at these patterns, making it a natural fit for relationship-heavy Nostr queries.
License
Same as ORLY relay project.