Migration Guide
This guide helps you migrate from other databases to StrataDB.
From MongoDB
If you're currently using MongoDB, StrataDB provides a familiar API with additional type safety benefits.
Key Differences
| MongoDB | StrataDB | Notes |
|---|---|---|
MongoClient | Strata | Main database class |
collection.insertOne() | collection.insertOne() | Same API |
collection.find() | collection.find() | Same API with type safety |
| Schema validation | Schema definitions with types | Compile-time validation |
| ObjectId | UUID strings | Auto-generated IDs |
| Multiple server setup | Single file or in-memory | Simpler deployment |
Migration Steps
- Install StrataDB:
bun add stratadb- Define your document types:
// MongoDB document
interface UserDocument {
_id: ObjectId;
name: string;
email: string;
age: number;
}
// StrataDB document
import type { Document } from 'stratadb'
type User = Document<{
name: string
email: string
age: number
}>- Create schemas with indexes:
// MongoDB: Schema defined in database
// StrataDB: Schema defined in code
import { createSchema } from 'stratadb'
const userSchema = createSchema<User>()
.field('name', { type: 'TEXT', indexed: true })
.field('email', { type: 'TEXT', indexed: true, unique: true })
.field('age', { type: 'INTEGER', indexed: true })
.build()- Update database connection:
// ❌ MongoDB approach
import { MongoClient } from 'mongodb'
const client = new MongoClient('mongodb://localhost:27017')
const db = client.db('myapp')
const users = db.collection('users')
// ✅ StrataDB approach
import { Strata } from 'stratadb'
const db = new Strata({ database: 'myapp.db' })
const users = db.collection('users', userSchema)- Update your operations (API is similar):
// MongoDB and StrataDB have similar APIs
await users.insertOne({ name: 'Alice', email: 'alice@example.com', age: 30 })
await users.find({ age: { $gte: 18 } })
// Note: StrataDB uses simpler APIs - operations work by ID, not filters
await users.updateOne('user-id-here', { name: 'Alice Smith' }) // Update by known ID
await users.deleteOne('user-id-here') // Delete by known IDHandling MongoDB-Specific Features
ObjectId to UUID Migration
MongoDB uses ObjectId by default, while StrataDB uses UUIDs. If you need to migrate existing ObjectId data:
type User = Document<{
originalId?: string // Store old ObjectId for migration
name: string
email: string
}>
// When migrating existing data:
const migrateFromMongo = async () => {
// Import from MongoDB (pseudo-code)
const mongoUsers = await mongoUsersCollection.find({}).toArray()
for (const mongoUser of mongoUsers) {
await stratadbUsers.insertOne({
originalId: mongoUser._id.toString(), // Store old ID for reference
name: mongoUser.name,
email: mongoUser.email,
})
}
}Aggregation Pipeline Differences
MongoDB has complex aggregation pipelines. StrataDB doesn't support the full pipeline, so you'll need to handle complex operations differently:
// ❌ MongoDB aggregation
const result = await users.aggregate([
{ $match: { age: { $gte: 18 } } },
{ $group: { _id: '$status', count: { $sum: 1 } } }
]).toArray()
// ✅ StrataDB alternative - simpler queries + application logic
const adults = await users.find({ age: { $gte: 18 } })
const statusCounts = adults.reduce((acc, user) => {
acc[user.status] = (acc[user.status] || 0) + 1
return acc
}, {} as Record<string, number>)Text Search Migration
MongoDB has built-in text search. For similar functionality in StrataDB:
// MongoDB text search
const results = await users.find({ $text: { $search: 'search term' } })
// ✅ StrataDB alternative - use LIKE or regex with indexed fields
const userSchema = createSchema<User>()
.field('name', { type: 'TEXT', indexed: true })
.field('email', { type: 'TEXT', indexed: true })
.build()
// Then search indexed fields
const results = await users.find({
$or: [
{ name: { $like: '%search%' } },
{ email: { $like: '%search%' } }
]
})From Prisma/TypeORM
If you're using Prisma or TypeORM, the main difference is that StrataDB is document-oriented rather than relational.
Migration Considerations
Schema Definition
// Prisma schema.prisma
// model User {
// id Int @id @default(autoincrement())
// name String
// email String @unique
// posts Post[]
// }
// ✅ StrataDB approach
type User = Document<{
name: string
email: string
posts?: Post[] // Embed related data or use references
}>
const userSchema = createSchema<User>()
.field('name', { type: 'TEXT', indexed: true })
.field('email', { type: 'TEXT', indexed: true, unique: true })
.build()Relationship Handling
// ❌ Relational approach with joins
const userWithPosts = await prisma.user.findUnique({
where: { id: 1 },
include: { posts: true }
})
// ✅ Document approach - either embed or reference
// Option 1: Embed documents
type UserWithPosts = Document<{
name: string
email: string
posts: Post[] // Embedded in same document
}>
// Option 2: Use references
type User = Document<{
name: string
email: string
postIds: string[] // References to other documents
}>From Raw SQLite
If you're currently using raw SQLite with JSON columns, StrataDB provides a structured approach.
Benefits of Migrating from Raw SQLite
- Type Safety: Compile-time validation of queries
- Simplified Schema Management: Define indexes in code instead of SQL
- MongoDB-like API: Familiar interface for document operations
- Built-in Validation: Schema validation without extra code
Migration Steps
- Analyze your current table structure:
-- Current raw SQLite table
CREATE TABLE users (
id TEXT PRIMARY KEY,
data TEXT NOT NULL -- JSON data
);- Define StrataDB schemas:
type UserData = {
name: string
email: string
age: number
metadata: Record<string, unknown>
}
type User = Document<UserData>
const userSchema = createSchema<User>()
.field('name', { type: 'TEXT', indexed: true })
.field('email', { type: 'TEXT', indexed: true, unique: true })
.field('age', { type: 'INTEGER', indexed: true })
.build()- Migrate existing data:
// Migration script
const migrateData = async () => {
// Read from old table
const oldUsers = db.prepare('SELECT id, data FROM users').all()
for (const oldUser of oldUsers) {
const userData = JSON.parse(oldUser.data) as UserData
// Insert into new StrataDB collection
await users.insertOne({
id: oldUser.id, // Preserve existing IDs
...userData
})
}
}- Update your queries:
// ❌ Raw SQLite with manual JSON extraction
const stmt = db.prepare(`
SELECT * FROM users
WHERE json_extract(data, '$.age') >= ?
AND json_extract(data, '$.status') = ?
`)
// ✅ StrataDB with type safety
const adults = await users.find({
age: { $gte: 18 },
status: 'active'
})From Other Document Databases
Firebase/Firestore Migration
// ❌ Firebase approach
import { collection, addDoc, getDocs, query, where } from 'firebase/firestore'
const usersRef = collection(db, 'users')
const userDoc = await addDoc(usersRef, { name: 'Alice', email: 'alice@example.com' })
const adultUsers = await getDocs(query(usersRef, where('age', '>=', 18)))
// ✅ StrataDB approach
const result = await users.insertOne({ name: 'Alice', email: 'alice@example.com', age: 30 })
const adultUsers = await users.find({ age: { $gte: 18 } })CouchDB/PouchDB Migration
StrataDB doesn't support replication features, so consider this if you rely on synchronization.
Migration Checklist
- [ ] Update project dependencies (replace old database with StrataDB)
- [ ] Define TypeScript document types
- [ ] Create schema definitions with appropriate indexes
- [ ] Plan data migration strategy
- [ ] Update connection/setup code
- [ ] Convert queries to StrataDB syntax (should be similar)
- [ ] Implement any custom validation logic
- [ ] Update deployment configuration (no separate database server)
- [ ] Test all CRUD operations with new type safety
- [ ] Profile performance to optimize indexes
- [ ] Update error handling patterns
Handling Common Migration Challenges
Complex Queries
If you have complex SQL-like queries, you may need to handle additional processing in application code:
// For operations that require complex aggregation
const complexResults = async (minAge: number, minOrderCount: number) => {
// Find users with criteria
const users = await db.collection('users', userSchema).find({ age: { $gte: minAge } })
// Apply additional filters in application code
const results = []
for (const user of users) {
const orderCount = await db.collection('orders', orderSchema)
.count({ userId: user.id })
if (orderCount >= minOrderCount) {
results.push(user)
}
}
return results
}Database File Management
Unlike MongoDB which runs as a separate service, StrataDB uses files:
// For production deployment
const db = new Strata({
database: process.env.NODE_ENV === 'production'
? '/var/lib/myapp/database.db' // Production path
: './dev.db' // Development path
})Backup Strategy
Since StrataDB uses a SQLite file, backups are simpler:
# Simple file backup
cp myapp.db myapp.db.backup.$(date +%Y%m%d)
# Or use SQLite's built-in backup command
sqlite3 myapp.db ".backup myapp.db.backup"By following this guide, you should be able to migrate your existing database to StrataDB while gaining type safety and simpler deployment.