implement preliminary implementation of graph data model
This commit is contained in:
@@ -7,24 +7,51 @@ import (
|
||||
|
||||
// applySchema creates Neo4j constraints and indexes for Nostr events
|
||||
// Neo4j uses Cypher queries to define schema constraints and indexes
|
||||
// Includes both base Nostr relay schema and optional WoT extensions
|
||||
func (n *N) applySchema(ctx context.Context) error {
|
||||
n.Logger.Infof("applying Nostr schema to neo4j")
|
||||
|
||||
// Create constraints and indexes using Cypher queries
|
||||
// Constraints ensure uniqueness and are automatically indexed
|
||||
constraints := []string{
|
||||
// === Base Nostr Relay Schema (NIP-01 Queries) ===
|
||||
|
||||
// Unique constraint on Event.id (event ID must be unique)
|
||||
"CREATE CONSTRAINT event_id_unique IF NOT EXISTS FOR (e:Event) REQUIRE e.id IS UNIQUE",
|
||||
|
||||
// Unique constraint on Author.pubkey (author public key must be unique)
|
||||
// Note: Author nodes are for NIP-01 query support (REQ filters)
|
||||
"CREATE CONSTRAINT author_pubkey_unique IF NOT EXISTS FOR (a:Author) REQUIRE a.pubkey IS UNIQUE",
|
||||
|
||||
// Unique constraint on Marker.key (marker key must be unique)
|
||||
"CREATE CONSTRAINT marker_key_unique IF NOT EXISTS FOR (m:Marker) REQUIRE m.key IS UNIQUE",
|
||||
|
||||
// === Social Graph Event Processing Schema ===
|
||||
|
||||
// Unique constraint on ProcessedSocialEvent.event_id
|
||||
// Tracks which social events (kinds 0, 3, 1984, 10000) have been processed
|
||||
"CREATE CONSTRAINT processedSocialEvent_event_id IF NOT EXISTS FOR (e:ProcessedSocialEvent) REQUIRE e.event_id IS UNIQUE",
|
||||
|
||||
// === WoT Extension Schema ===
|
||||
|
||||
// Unique constraint on NostrUser.pubkey
|
||||
// Note: NostrUser nodes are for social graph/WoT (separate from Author nodes)
|
||||
"CREATE CONSTRAINT nostrUser_pubkey IF NOT EXISTS FOR (n:NostrUser) REQUIRE n.pubkey IS UNIQUE",
|
||||
|
||||
// Unique constraint on SetOfNostrUserWotMetricsCards.observee_pubkey
|
||||
"CREATE CONSTRAINT setOfNostrUserWotMetricsCards_observee_pubkey IF NOT EXISTS FOR (n:SetOfNostrUserWotMetricsCards) REQUIRE n.observee_pubkey IS UNIQUE",
|
||||
|
||||
// Unique constraint on NostrUserWotMetricsCard (customer_id, observee_pubkey)
|
||||
"CREATE CONSTRAINT nostrUserWotMetricsCard_unique_combination_1 IF NOT EXISTS FOR (n:NostrUserWotMetricsCard) REQUIRE (n.customer_id, n.observee_pubkey) IS UNIQUE",
|
||||
|
||||
// Unique constraint on NostrUserWotMetricsCard (observer_pubkey, observee_pubkey)
|
||||
"CREATE CONSTRAINT nostrUserWotMetricsCard_unique_combination_2 IF NOT EXISTS FOR (n:NostrUserWotMetricsCard) REQUIRE (n.observer_pubkey, n.observee_pubkey) IS UNIQUE",
|
||||
}
|
||||
|
||||
// Additional indexes for query optimization
|
||||
indexes := []string{
|
||||
// === Base Nostr Relay Indexes ===
|
||||
|
||||
// Index on Event.kind for kind-based queries
|
||||
"CREATE INDEX event_kind IF NOT EXISTS FOR (e:Event) ON (e.kind)",
|
||||
|
||||
@@ -45,6 +72,37 @@ func (n *N) applySchema(ctx context.Context) error {
|
||||
|
||||
// Composite index for tag queries (type + value)
|
||||
"CREATE INDEX tag_type_value IF NOT EXISTS FOR (t:Tag) ON (t.type, t.value)",
|
||||
|
||||
// === Social Graph Event Processing Indexes ===
|
||||
|
||||
// Index on ProcessedSocialEvent for quick lookup by pubkey and kind
|
||||
"CREATE INDEX processedSocialEvent_pubkey_kind IF NOT EXISTS FOR (e:ProcessedSocialEvent) ON (e.pubkey, e.event_kind)",
|
||||
|
||||
// Index on ProcessedSocialEvent.superseded_by to filter active events
|
||||
"CREATE INDEX processedSocialEvent_superseded IF NOT EXISTS FOR (e:ProcessedSocialEvent) ON (e.superseded_by)",
|
||||
|
||||
// === WoT Extension Indexes ===
|
||||
|
||||
// NostrUser indexes for trust metrics
|
||||
"CREATE INDEX nostrUser_hops IF NOT EXISTS FOR (n:NostrUser) ON (n.hops)",
|
||||
"CREATE INDEX nostrUser_personalizedPageRank IF NOT EXISTS FOR (n:NostrUser) ON (n.personalizedPageRank)",
|
||||
"CREATE INDEX nostrUser_influence IF NOT EXISTS FOR (n:NostrUser) ON (n.influence)",
|
||||
"CREATE INDEX nostrUser_verifiedFollowerCount IF NOT EXISTS FOR (n:NostrUser) ON (n.verifiedFollowerCount)",
|
||||
"CREATE INDEX nostrUser_verifiedMuterCount IF NOT EXISTS FOR (n:NostrUser) ON (n.verifiedMuterCount)",
|
||||
"CREATE INDEX nostrUser_verifiedReporterCount IF NOT EXISTS FOR (n:NostrUser) ON (n.verifiedReporterCount)",
|
||||
"CREATE INDEX nostrUser_followerInput IF NOT EXISTS FOR (n:NostrUser) ON (n.followerInput)",
|
||||
|
||||
// NostrUserWotMetricsCard indexes
|
||||
"CREATE INDEX nostrUserWotMetricsCard_customer_id IF NOT EXISTS FOR (n:NostrUserWotMetricsCard) ON (n.customer_id)",
|
||||
"CREATE INDEX nostrUserWotMetricsCard_observer_pubkey IF NOT EXISTS FOR (n:NostrUserWotMetricsCard) ON (n.observer_pubkey)",
|
||||
"CREATE INDEX nostrUserWotMetricsCard_observee_pubkey IF NOT EXISTS FOR (n:NostrUserWotMetricsCard) ON (n.observee_pubkey)",
|
||||
"CREATE INDEX nostrUserWotMetricsCard_hops IF NOT EXISTS FOR (n:NostrUserWotMetricsCard) ON (n.hops)",
|
||||
"CREATE INDEX nostrUserWotMetricsCard_personalizedPageRank IF NOT EXISTS FOR (n:NostrUserWotMetricsCard) ON (n.personalizedPageRank)",
|
||||
"CREATE INDEX nostrUserWotMetricsCard_influence IF NOT EXISTS FOR (n:NostrUserWotMetricsCard) ON (n.influence)",
|
||||
"CREATE INDEX nostrUserWotMetricsCard_verifiedFollowerCount IF NOT EXISTS FOR (n:NostrUserWotMetricsCard) ON (n.verifiedFollowerCount)",
|
||||
"CREATE INDEX nostrUserWotMetricsCard_verifiedMuterCount IF NOT EXISTS FOR (n:NostrUserWotMetricsCard) ON (n.verifiedMuterCount)",
|
||||
"CREATE INDEX nostrUserWotMetricsCard_verifiedReporterCount IF NOT EXISTS FOR (n:NostrUserWotMetricsCard) ON (n.verifiedReporterCount)",
|
||||
"CREATE INDEX nostrUserWotMetricsCard_followerInput IF NOT EXISTS FOR (n:NostrUserWotMetricsCard) ON (n.followerInput)",
|
||||
}
|
||||
|
||||
// Execute all constraint creation queries
|
||||
@@ -75,11 +133,21 @@ func (n *N) dropAll(ctx context.Context) error {
|
||||
return fmt.Errorf("failed to drop all data: %w", err)
|
||||
}
|
||||
|
||||
// Drop all constraints
|
||||
// Drop all constraints (base + social graph + WoT)
|
||||
constraints := []string{
|
||||
// Base constraints
|
||||
"DROP CONSTRAINT event_id_unique IF EXISTS",
|
||||
"DROP CONSTRAINT author_pubkey_unique IF EXISTS",
|
||||
"DROP CONSTRAINT marker_key_unique IF EXISTS",
|
||||
|
||||
// Social graph constraints
|
||||
"DROP CONSTRAINT processedSocialEvent_event_id IF EXISTS",
|
||||
|
||||
// WoT constraints
|
||||
"DROP CONSTRAINT nostrUser_pubkey IF EXISTS",
|
||||
"DROP CONSTRAINT setOfNostrUserWotMetricsCards_observee_pubkey IF EXISTS",
|
||||
"DROP CONSTRAINT nostrUserWotMetricsCard_unique_combination_1 IF EXISTS",
|
||||
"DROP CONSTRAINT nostrUserWotMetricsCard_unique_combination_2 IF EXISTS",
|
||||
}
|
||||
|
||||
for _, constraint := range constraints {
|
||||
@@ -87,8 +155,9 @@ func (n *N) dropAll(ctx context.Context) error {
|
||||
// Ignore errors as constraints may not exist
|
||||
}
|
||||
|
||||
// Drop all indexes
|
||||
// Drop all indexes (base + social graph + WoT)
|
||||
indexes := []string{
|
||||
// Base indexes
|
||||
"DROP INDEX event_kind IF EXISTS",
|
||||
"DROP INDEX event_created_at IF EXISTS",
|
||||
"DROP INDEX event_serial IF EXISTS",
|
||||
@@ -96,6 +165,29 @@ func (n *N) dropAll(ctx context.Context) error {
|
||||
"DROP INDEX tag_type IF EXISTS",
|
||||
"DROP INDEX tag_value IF EXISTS",
|
||||
"DROP INDEX tag_type_value IF EXISTS",
|
||||
|
||||
// Social graph indexes
|
||||
"DROP INDEX processedSocialEvent_pubkey_kind IF EXISTS",
|
||||
"DROP INDEX processedSocialEvent_superseded IF EXISTS",
|
||||
|
||||
// WoT indexes
|
||||
"DROP INDEX nostrUser_hops IF EXISTS",
|
||||
"DROP INDEX nostrUser_personalizedPageRank IF EXISTS",
|
||||
"DROP INDEX nostrUser_influence IF EXISTS",
|
||||
"DROP INDEX nostrUser_verifiedFollowerCount IF EXISTS",
|
||||
"DROP INDEX nostrUser_verifiedMuterCount IF EXISTS",
|
||||
"DROP INDEX nostrUser_verifiedReporterCount IF EXISTS",
|
||||
"DROP INDEX nostrUser_followerInput IF EXISTS",
|
||||
"DROP INDEX nostrUserWotMetricsCard_customer_id IF EXISTS",
|
||||
"DROP INDEX nostrUserWotMetricsCard_observer_pubkey IF EXISTS",
|
||||
"DROP INDEX nostrUserWotMetricsCard_observee_pubkey IF EXISTS",
|
||||
"DROP INDEX nostrUserWotMetricsCard_hops IF EXISTS",
|
||||
"DROP INDEX nostrUserWotMetricsCard_personalizedPageRank IF EXISTS",
|
||||
"DROP INDEX nostrUserWotMetricsCard_influence IF EXISTS",
|
||||
"DROP INDEX nostrUserWotMetricsCard_verifiedFollowerCount IF EXISTS",
|
||||
"DROP INDEX nostrUserWotMetricsCard_verifiedMuterCount IF EXISTS",
|
||||
"DROP INDEX nostrUserWotMetricsCard_verifiedReporterCount IF EXISTS",
|
||||
"DROP INDEX nostrUserWotMetricsCard_followerInput IF EXISTS",
|
||||
}
|
||||
|
||||
for _, index := range indexes {
|
||||
|
||||
Reference in New Issue
Block a user