UNPKG

@andrejs1979/document

Version:

MongoDB-compatible document database for NoSQL

455 lines 16 kB
/** * NoSQL - Main Document Database Class * MongoDB-compatible document database with vector integration */ import { DocumentError } from './types'; import { DocumentStorage } from './storage/document-storage'; import { MongoQueryEngine } from './operations/query-engine'; import { DocumentIndexManager } from './indexes/index-manager'; import { RelationshipManager } from './relationships/relationship-manager'; import { HybridSearchEngine } from './operations/hybrid-search'; import { BulkOperationsManager } from './operations/bulk-operations'; import { TaggingSystem } from './metadata/tagging-system'; /** * Main NoSQL Document Database class */ export class EdgeDocumentDB { storage; queryEngine; indexManager; relationshipManager; hybridSearchEngine; bulkOperationsManager; taggingSystem; config; initialized = false; constructor(config) { this.config = config; this.storage = new DocumentStorage(config); this.indexManager = new DocumentIndexManager(config); this.queryEngine = new MongoQueryEngine(config.d1Database, this.indexManager); this.relationshipManager = new RelationshipManager(this.storage, config); this.hybridSearchEngine = new HybridSearchEngine(this.storage, this.queryEngine, config); this.bulkOperationsManager = new BulkOperationsManager(this.storage, config); this.taggingSystem = new TaggingSystem(this.storage, config); } /** * Initialize the document database */ async initialize() { if (this.initialized) return; try { await this.storage.initialize(); this.initialized = true; console.log(`EdgeDocumentDB initialized: ${this.config.name}`); } catch (error) { throw new DocumentError(`Database initialization failed: ${error.message}`, 'INIT_ERROR'); } } // =============================== // Core CRUD Operations // =============================== /** * Insert a single document */ async insertOne(collection, document) { await this.ensureInitialized(); // Auto-tag if enabled if (this.config.vectorConfig?.autoEmbedding) { document.tags = await this.taggingSystem.autoTag(collection, document); } return await this.storage.insertOne(collection, document); } /** * Insert multiple documents */ async insertMany(collection, documents) { await this.ensureInitialized(); // Auto-tag documents if enabled if (this.config.vectorConfig?.autoEmbedding) { for (const document of documents) { document.tags = await this.taggingSystem.autoTag(collection, document); } } return await this.storage.insertMany(collection, documents); } /** * Find documents by filter */ async find(collection, filter = {}, options = {}) { await this.ensureInitialized(); // Track query pattern for auto-indexing this.indexManager.trackQueryPattern(this.config.name, collection, filter, options); return await this.storage.find(collection, filter, options); } /** * Find a single document */ async findOne(collection, filter = {}, options = {}) { await this.ensureInitialized(); return await this.storage.findOne(collection, filter, options); } /** * Update a single document */ async updateOne(collection, filter, update, options = {}) { await this.ensureInitialized(); if (this.config.enableRelationships) { return await this.relationshipManager.updateWithRelationships(collection, filter, update); } else { return await this.storage.updateOne(collection, filter, update, options); } } /** * Update multiple documents */ async updateMany(collection, filter, update, options = {}) { await this.ensureInitialized(); // For bulk updates, use the bulk operations manager const bulkOps = [{ updateMany: { filter, update: update, upsert: options.upsert, arrayFilters: options.arrayFilters } }]; const bulkResult = await this.bulkOperationsManager.bulkWrite(collection, bulkOps); return { acknowledged: bulkResult.acknowledged, matchedCount: bulkResult.matchedCount, modifiedCount: bulkResult.modifiedCount, upsertedId: Object.values(bulkResult.upsertedIds)[0], upsertedCount: bulkResult.upsertedCount }; } /** * Replace a single document */ async replaceOne(collection, filter, replacement, options = {}) { await this.ensureInitialized(); return await this.storage.updateOne(collection, filter, replacement, options); } /** * Delete a single document */ async deleteOne(collection, filter) { await this.ensureInitialized(); if (this.config.enableRelationships) { await this.relationshipManager.deleteWithRelationships(collection, filter); return { acknowledged: true, deletedCount: 1 }; } else { return await this.storage.deleteOne(collection, filter); } } /** * Delete multiple documents */ async deleteMany(collection, filter) { await this.ensureInitialized(); return await this.storage.deleteMany(collection, filter); } /** * Count documents matching filter */ async countDocuments(collection, filter = {}) { await this.ensureInitialized(); return await this.storage.countDocuments(collection, filter); } // =============================== // Advanced Query Operations // =============================== /** * Execute aggregation pipeline */ async aggregate(collection, pipeline, options = {}) { await this.ensureInitialized(); return await this.queryEngine.executeAggregation(this.config.name, collection, pipeline, options); } /** * Explain query execution plan */ async explain(collection, filter, options = {}) { await this.ensureInitialized(); return await this.queryEngine.explainQuery(this.config.name, collection, filter, options); } // =============================== // Hybrid Search Operations // =============================== /** * Hybrid search combining text, vector, and metadata */ async hybridSearch(collection, query) { await this.ensureInitialized(); return await this.hybridSearchEngine.hybridSearch(this.config.name, collection, query); } /** * Text search with optional vector boost */ async textSearch(collection, searchText, options = {}) { await this.ensureInitialized(); return await this.hybridSearchEngine.textSearch(this.config.name, collection, searchText, options); } /** * Vector similarity search */ async vectorSearch(collection, queryVector, options = {}) { await this.ensureInitialized(); return await this.hybridSearchEngine.vectorSearch(this.config.name, collection, queryVector, options); } /** * Semantic search using text embedding */ async semanticSearch(collection, searchText, options = {}) { await this.ensureInitialized(); return await this.hybridSearchEngine.semanticSearch(this.config.name, collection, searchText, options); } /** * Find similar documents */ async findSimilarDocuments(collection, documentId, options = {}) { await this.ensureInitialized(); return await this.hybridSearchEngine.findSimilarDocuments(this.config.name, collection, documentId, options); } /** * Get personalized recommendations */ async getRecommendations(collection, userHistory, options = {}) { await this.ensureInitialized(); return await this.hybridSearchEngine.getRecommendations(this.config.name, collection, userHistory, options); } // =============================== // Relationship Operations // =============================== /** * Define a relationship between collections */ async defineRelationship(sourceCollection, targetCollection, relationship) { await this.ensureInitialized(); return await this.relationshipManager.defineRelationship(sourceCollection, targetCollection, relationship); } /** * Populate document with related data */ async populate(collection, document, populateOptions) { await this.ensureInitialized(); return await this.relationshipManager.populate(collection, document, populateOptions); } /** * Find documents with automatic population */ async findWithPopulate(collection, filter, populateOptions, findOptions = {}) { await this.ensureInitialized(); return await this.relationshipManager.findWithPopulate(collection, filter, populateOptions, findOptions); } // =============================== // Bulk Operations // =============================== /** * Execute bulk write operations */ async bulkWrite(collection, operations, options = {}) { await this.ensureInitialized(); return await this.bulkOperationsManager.bulkWrite(collection, operations, options); } /** * Stream insert large datasets */ async streamInsert(collection, documentStream, options = {}) { await this.ensureInitialized(); return await this.bulkOperationsManager.streamInsert(collection, documentStream, options); } /** * Create a document stream for real-time processing */ createDocumentStream(collection, config) { return this.bulkOperationsManager.createDocumentStream(collection, config); } // =============================== // Index Management // =============================== /** * Create an index */ async createIndex(collection, indexSpec) { await this.ensureInitialized(); return await this.indexManager.createIndex(this.config.name, collection, indexSpec); } /** * Drop an index */ async dropIndex(collection, indexName) { await this.ensureInitialized(); return await this.indexManager.dropIndex(this.config.name, collection, indexName); } /** * List all indexes for a collection */ async listIndexes(collection) { await this.ensureInitialized(); return await this.indexManager.listIndexes(this.config.name, collection); } /** * Get index recommendations */ async getIndexRecommendations(collection) { await this.ensureInitialized(); return await this.indexManager.getIndexRecommendations(this.config.name, collection); } /** * Auto-create indexes based on query patterns */ async autoCreateIndexes(collection) { await this.ensureInitialized(); return await this.indexManager.autoCreateIndexes(this.config.name, collection); } // =============================== // Tagging and Metadata // =============================== /** * Auto-tag a document */ async autoTag(collection, document, config = {}) { await this.ensureInitialized(); return await this.taggingSystem.autoTag(collection, document, config); } /** * Tag a document */ async tagDocument(collection, documentId, tags, options = {}) { await this.ensureInitialized(); return await this.taggingSystem.tagDocument(collection, documentId, tags, options); } /** * Find documents by tags */ async findByTags(collection, tags, options = {}) { await this.ensureInitialized(); return await this.taggingSystem.findByTags(collection, tags, options); } /** * Get tag suggestions */ async getTagSuggestions(collection, document, options = {}) { await this.ensureInitialized(); return await this.taggingSystem.getTagSuggestions(collection, document, options); } /** * Get tag statistics */ async getTagStats(collection, options = {}) { await this.ensureInitialized(); return await this.taggingSystem.getTagStats(collection, options); } // =============================== // Database Management // =============================== /** * Get database statistics */ async stats() { await this.ensureInitialized(); try { // This is a simplified implementation // In a real scenario, you'd aggregate across all collections const totalDocs = await this.storage.countDocuments('*', {}); return { totalDocuments: totalDocs, totalSize: 0, // Would calculate actual size averageDocumentSize: 0, indexCount: 0, totalIndexSize: 0, collections: 0, vectorDocuments: 0, lastOptimized: new Date() }; } catch (error) { throw new DocumentError(`Failed to get database stats: ${error.message}`, 'STATS_ERROR'); } } /** * Health check */ async ping() { try { return await this.storage.ping(); } catch (error) { return false; } } /** * Close database connections */ async close() { try { await this.bulkOperationsManager.stopAllStreams(); this.hybridSearchEngine.clearSearchCache(); this.relationshipManager.clearPopulateCache(); console.log(`EdgeDocumentDB closed: ${this.config.name}`); } catch (error) { console.warn('Error during database close:', error.message); } } // =============================== // Static Factory Methods // =============================== /** * Create a document database with simplified configuration */ static async create(config) { const dbConfig = { name: config.name, d1Database: config.d1Database, kvStore: config.kvStore, r2Bucket: config.r2Bucket, // Default configuration maxDocumentSize: 16 * 1024 * 1024, // 16MB queryTimeout: 30000, batchSize: 100, enableQueryCache: true, queryCacheTTL: 300, cacheSize: 100, enableAutoIndexing: true, autoIndexThreshold: 1000, maxIndexedFields: 20, vectorConfig: { enabled: true, defaultDimensions: 1536, defaultModel: 'text-embedding-ada-002', autoEmbedding: false, embeddingFields: ['content', 'text', 'description'] }, enableValidation: true, enableSchemaEvolution: true, enableChangeStreams: true, maxChangeStreamConnections: 1000, enableQueryLogging: false, enablePerformanceMetrics: true, enableRelationships: true, populateDepth: 3, bulkWriteBatchSize: 1000, bulkWriteParallelism: 4, // Override with user options ...config.options }; const db = new EdgeDocumentDB(dbConfig); await db.initialize(); return db; } // =============================== // Private Methods // =============================== async ensureInitialized() { if (!this.initialized) { await this.initialize(); } } } //# sourceMappingURL=edge-document-db.js.map