You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
So, I had an idea about plugins for adding a change in language and protocol used to connect to the same backing data store. let me know what you think, if it would be worth doing, etc...
Executive Summary
This proposal outlines a plugin architecture that would allow NornicDB to support multiple database protocols and query languages, enabling users to connect using their existing drivers (Neo4j, MongoDB, PostgreSQL, etc.) while all operations execute against the same underlying NornicDB storage engine.
Key Benefits:
Use existing MongoDB drivers to connect to NornicDB
MongoDB-style queries with built-in vector search and embeddings
No vendor lock-in - choose your preferred query language
Key Insight: All query language plugins translate to the same existing AST.
No new intermediate representation needed - we leverage what's already built.
Core Plugin Interfaces
// pkg/plugin/protocol.go// ProtocolPlugin defines a wire protocol handler (Bolt, MongoDB Wire, PostgreSQL Wire, etc.)typeProtocolPlugininterface {
// MetadataName() stringVersion() stringDescription() string// LifecycleInit(configPluginConfig) errorStart(executorQueryExecutor) errorStop(ctx context.Context) error// ConfigurationDefaultPort() intConfigSchema() map[string]ConfigField
}
// QueryLanguagePlugin defines a query language handler.// Plugins can choose their implementation strategy (see "Plugin Implementation Strategies" below).typeQueryLanguagePlugininterface {
// MetadataName() string// "cypher", "mql", "sql", "graphql"Version() string// Strategy returns which implementation approach this plugin usesStrategy() PluginStrategy// CapabilitiesCapabilities() QueryCapabilities
}
// PluginStrategy indicates how the plugin processes queriestypePluginStrategyintconst (
// StrategyAST - Plugin produces AST, NornicDB executes it// Best for: New languages, clean separation, leverages existing optimizerStrategyASTPluginStrategy=iota// StrategyDirect - Plugin handles everything: parse + execute// Best for: Maximum control, custom optimizations, streaming executionStrategyDirect
)
// ASTProducerPlugin - Strategy A/B: Produce AST for NornicDB to executetypeASTProducerPlugininterface {
QueryLanguagePlugin// Parse produces NornicDB's AST structure// Can use ANTLR, hand-rolled parser, or delegate to existing parserParse(querystring) (*cypher.AST, error)
}
// DirectExecutorPlugin - Strategy C: Handle everything directly// Like NornicDB's internal Cypher executor - full control over parse/execute flowtypeDirectExecutorPlugininterface {
QueryLanguagePlugin// Execute handles the entire query lifecycle// Plugin maintains its own parsing, routing, caching, optimizationExecute(ctx context.Context, querystring, paramsmap[string]any, storage storage.Engine) (*ExecuteResult, error)
}
Plugin Implementation Strategies
Plugins can choose their parsing/execution approach based on their needs:
Strategy A: ANTLR-Style Parser → AST
Traditional compiler approach using grammar-based parsing.
Existing Work:Mimir PR #18 contains an ANTLR-based
Cypher parser that was not merged due to performance overhead (~5-10ms vs inline's ~0.5ms).
This could be extracted as an optional plugin for users who prefer:
Strict grammar validation
Better error messages
Easier grammar extensions
Standard tooling (ANTLR ecosystem)
// pkg/plugins/antlr-cypher/plugin.go// Based on: https://github.com/orneryd/Mimir/pull/18typeANTLRCypherPluginstruct {
// ANTLR-generated parser from PR #18lexer*parser.CypherLexerparser*parser.CypherParser
}
func (p*ANTLRCypherPlugin) Name() string { return"antlr-cypher" }
func (p*ANTLRCypherPlugin) Strategy() PluginStrategy { returnStrategyAST }
func (p*ANTLRCypherPlugin) Parse(querystring) (*cypher.AST, error) {
// 1. Lex into tokens (from PR #18's generated lexer)input:=antlr.NewInputStream(query)
lexer:=parser.NewCypherLexer(input)
tokens:=antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
// 2. Parse into ANTLR Cypher ASTcypherParser:=parser.NewCypherParser(tokens)
tree:=cypherParser.OC_Cypher() // Root rule from OpenCypher grammar// 3. Transform ANTLR AST → NornicDB ASTvisitor:=&NornicASTVisitor{}
returnvisitor.Visit(tree).(*cypher.AST), nil
}
// Configuration in nornicdb.yaml:// plugins:// cypher:// parser: antlr # Use ANTLR plugin instead of built-in inline parser// # parser: inline # Default - fast inline parser
Each protocol plugin handles its own authentication
Unified authorization layer at storage level
Audit logging across all protocols
Plugin sandboxing for untrusted plugins
Comparison: MongoDB Atlas vs NornicDB
Feature
MongoDB Atlas
NornicDB + MongoDB Plugin
Document Storage
✅ Native
✅ Via graph nodes
Vector Search
✅ Atlas Vector Search
✅ Built-in, faster
Graph Queries
❌ $graphLookup (limited)
✅ Native graph engine
$lookup Performance
⚠️ Slow (joins)
✅ Fast (graph traversal)
Auto-embeddings
❌ External
✅ Built-in
Memory Decay
❌ No
✅ Native
Self-hosted
⚠️ Enterprise only
✅ Always
Protocol Flexibility
❌ MongoDB only
✅ Multi-protocol
Conclusion
The plugin architecture would position NornicDB as a universal database adapter - users can connect with their preferred tools and query languages while benefiting from NornicDB's graph-native storage, vector search, and memory features.
The MongoDB plugin specifically addresses a large market:
Millions of MongoDB developers
Existing applications that could benefit from graph + vector capabilities
Teams wanting to migrate from MongoDB without rewriting code
Recommended Next Steps:
Review and approve this proposal
Create detailed technical design for plugin interfaces
Prototype MongoDB Wire Protocol handler
Benchmark MQL translation overhead
Community feedback on priority of additional protocols
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
So, I had an idea about plugins for adding a change in language and protocol used to connect to the same backing data store. let me know what you think, if it would be worth doing, etc...
Executive Summary
This proposal outlines a plugin architecture that would allow NornicDB to support multiple database protocols and query languages, enabling users to connect using their existing drivers (Neo4j, MongoDB, PostgreSQL, etc.) while all operations execute against the same underlying NornicDB storage engine.
Key Benefits:
Current Architecture
NornicDB currently supports two protocols:
Key Interfaces
QueryExecutor (pkg/bolt/server.go):
Storage Engine (pkg/storage):
Proposed Plugin Architecture
High-Level Design
Key Insight: All query language plugins translate to the same existing AST.
No new intermediate representation needed - we leverage what's already built.
Core Plugin Interfaces
Plugin Implementation Strategies
Plugins can choose their parsing/execution approach based on their needs:
Strategy A: ANTLR-Style Parser → AST
Traditional compiler approach using grammar-based parsing.
Why Extract PR #18 as a Plugin:
Users could switch parsers via config:
Pros: Clean grammar, auto-generated parser, good error messages, standard tooling
Cons: Slower than hand-rolled (~5-10ms overhead), grammar maintenance
Strategy B: Reuse/Delegate to Existing Parser
For languages similar to Cypher, or when a fast parser already exists.
Strategy C: Custom Stream-Parse-Execute (Like NornicDB)
Full control - plugin handles everything. This is how NornicDB's Cypher executor works internally.
Strategy Comparison
Hybrid Approach
Plugins can even mix strategies - use AST for simple queries, direct execution for complex ones:
Leveraging the Existing AST
NornicDB already has a comprehensive AST in
pkg/cypher/ast_builder.go:Key Insight: Query language plugins don't need a new intermediate representation.
They translate directly to NornicDB's existing AST, which is then:
pkg/cache/query_cache.go(LRU + TTL)StorageExecutorMongoDB Protocol Plugin Design
Wire Protocol Implementation
MongoDB uses a binary wire protocol over TCP. The plugin would implement:
MQL to AST Translation
The key insight: MongoDB documents map naturally to graph nodes.
Vector Search Integration
MongoDB Atlas has vector search, but NornicDB's is built-in and more powerful:
Example: MongoDB Driver Usage
Plugin Loading Architecture
Plugin Discovery
Configuration
Implementation Phases
Phase 1: Plugin Infrastructure
ProtocolPluginandQueryLanguagePlugininterfacespkg/bolt) as a pluginpkg/server) as a pluginnornicdb.yamlPhase 2: AST Formalization
pkg/cypher/ast_builder.goas public APIPhase 3: MongoDB Protocol
find()→ASTClauseMatch+ASTClauseReturninsertOne/Many()→ASTClauseCreateupdateOne/Many()→ASTClauseMatch+ASTClauseSetdeleteOne/Many()→ASTClauseMatch+ASTClauseDelete$match→ASTClauseWhere$project→ASTClauseReturn$lookup→ASTRelationshiptraversal (major optimization!)$group→ Aggregation functions$vectorSearch→ASTClauseCallwith vector proceduresPhase 4: Additional Protocols
Technical Considerations
Performance
Query Translation Overhead: MQL → AST → Execution adds ~1-5ms latency
QueryCachehandles AST caching (LRU + TTL)Wire Protocol Parsing: Binary protocols are efficient
Graph vs Document Model: Some queries may be slower
$lookupbecomes faster as native graph traversalAST Considerations
AST Completeness: Current AST covers Cypher well, may need extensions for:
$bucket,$facet)ASTClauseExtensionfor plugin-specific nodesAST Stability: Plugins depend on AST structure
AST Validation: Plugins may generate invalid ASTs
ValidateAST()function to catch errors earlyCompatibility
MongoDB Features Not Supported:
NornicDB Features Available via MongoDB:
$vectorSearch)$lookup)$text)Security
Comparison: MongoDB Atlas vs NornicDB
Conclusion
The plugin architecture would position NornicDB as a universal database adapter - users can connect with their preferred tools and query languages while benefiting from NornicDB's graph-native storage, vector search, and memory features.
The MongoDB plugin specifically addresses a large market:
Recommended Next Steps:
Appendix A: MongoDB Wire Protocol Reference
Appendix B: Query Translation Examples
Beta Was this translation helpful? Give feedback.
All reactions