@dataql/mongodb-adapter
v1.4.0
Published
MongoDB adapter for DataQL with zero API changes
Maintainers
Readme
DataQL MongoDB Adapter
MongoDB Node.js Driver API adapter for DataQL - Migrate from MongoDB to DataQL with zero API changes.
Installation
npm install @dataql/mongodb-adapterQuick Start
import { MongoClient } from "@dataql/mongodb-adapter";
const client = new MongoClient("mongodb://localhost:27017/mydb", {
dataql: {
env: "prod",
},
});
await client.connect();
const db = client.db("myapp");
const collection = db.collection("users");
// Use familiar MongoDB operations
const result = await collection.insertOne({
name: "John Doe",
email: "[email protected]",
});
const users = await collection.find({ name: "John Doe" }).toArray();
console.log(users);
await client.close();Features
- Zero API Changes: Drop-in replacement for MongoDB Node.js driver
- Full MongoDB API Compatibility: All major operations supported
- ObjectId Support: Complete ObjectId implementation with utilities
- Cursor Operations: Full cursor support with chaining methods
- Bulk Operations: Efficient bulk write operations
- TypeScript Support: Full type safety and IntelliSense
- DataQL Infrastructure: No direct database connections - routes through DataQL's secure infrastructure
- DataQL Benefits: Offline-first, real-time sync, automatic scaling
Architecture
This adapter works through DataQL's infrastructure rather than connecting directly to MongoDB:
MongoDB Adapter → DataQL Core → Worker → Lambda → MongoDBKey Points:
- ✅ No Direct Database Connections: All operations route through DataQL's infrastructure
- ✅ Database Isolation: Each client gets their own dedicated database
- ✅ Automatic Routing: MongoDB URL is used for routing, not direct connection
- ✅ Infrastructure Benefits: Automatic scaling, caching, offline support
API Reference
MongoClient
import { MongoClient, connect } from "@dataql/mongodb-adapter";
// Constructor
const client = new MongoClient(url, options);
// Static connect method
const client = await MongoClient.connect(url, options);
// Helper function
const client = await connect(url, options);Options
interface MongoClientOptions {
// MongoDB compatibility options (ignored but supported for zero-API-change migration)
useNewUrlParser?: boolean;
useUnifiedTopology?: boolean;
maxPoolSize?: number;
serverSelectionTimeoutMS?: number;
// DataQL configuration - operations route through DataQL infrastructure
// Architecture: Client → Worker → Lambda → MongoDB (no direct database connections)
dataql?: {
appToken?: string;
env?: "dev" | "prod";
devPrefix?: string;
customConnection?: any; // For routing through other SDKs
};
}Database Operations
const db = client.db("database_name");
// Get collection
const collection = db.collection("collection_name");
// Database utilities
await db.listCollections();
await db.dropCollection("collection_name");
await db.dropDatabase();
await db.stats();Collection Operations
Insert Operations
// Insert one document
const result = await collection.insertOne(document);
console.log(result.insertedId);
// Insert multiple documents
const result = await collection.insertMany(documents);
console.log(result.insertedIds);Find Operations
// Find with cursor
const cursor = collection.find(filter, options);
const documents = await cursor.toArray();
// Find one document
const document = await collection.findOne(filter, options);
// Find with cursor methods
const results = await collection
.find({ status: "active" })
.sort({ createdAt: -1 })
.limit(10)
.skip(20)
.toArray();Update Operations
// Update one document
const result = await collection.updateOne(filter, update, options);
// Update multiple documents
const result = await collection.updateMany(filter, update, options);
// Replace one document
const result = await collection.replaceOne(filter, replacement, options);
// Find and update
const result = await collection.findOneAndUpdate(filter, update, {
returnDocument: "after",
});Delete Operations
// Delete one document
const result = await collection.deleteOne(filter);
// Delete multiple documents
const result = await collection.deleteMany(filter);
// Find and delete
const result = await collection.findOneAndDelete(filter);Bulk Operations
const operations = [
{ insertOne: { document: { name: "Alice" } } },
{ updateOne: { filter: { name: "Bob" }, update: { $set: { age: 30 } } } },
{ deleteOne: { filter: { name: "Charlie" } } },
];
const result = await collection.bulkWrite(operations);Count and Aggregation
// Count documents
const count = await collection.countDocuments(filter);
const estimatedCount = await collection.estimatedDocumentCount();
// Get distinct values
const values = await collection.distinct("fieldName", filter);
// Basic aggregation (limited support)
const results = await collection.aggregate(pipeline).toArray();ObjectId
import { ObjectId, BSON } from "@dataql/mongodb-adapter";
// Create ObjectId
const id = new ObjectId();
const idFromString = new ObjectId("507f1f77bcf86cd799439011");
// ObjectId methods
console.log(id.toString());
console.log(id.toHexString());
console.log(id.getTimestamp());
console.log(id.equals(otherId));
// Static methods
console.log(ObjectId.isValid(idString));
const id2 = ObjectId.createFromHexString(hexString);
// BSON utilities
const id3 = new BSON.ObjectId();Cursor Operations
const cursor = collection.find(filter);
// Get all results
const documents = await cursor.toArray();
// Iterate through results
await cursor.forEach((doc) => console.log(doc));
// Cursor transformations
const transformedCursor = cursor
.limit(10)
.skip(5)
.sort({ name: 1 })
.project({ name: 1, email: 1 });
// Async iteration
for await (const doc of cursor) {
console.log(doc);
}
// Manual iteration
while (await cursor.hasNext()) {
const doc = await cursor.next();
console.log(doc);
}Migration Guide
From MongoDB Driver
Replace your MongoDB driver import with the DataQL MongoDB adapter:
// Before
import { MongoClient } from "mongodb";
// After
import { MongoClient } from "@dataql/mongodb-adapter";All your existing MongoDB code will work without changes!
Configuration
Add DataQL configuration to your MongoDB connection options:
const client = new MongoClient(connectionString, {
// Your existing MongoDB options (for compatibility)
useNewUrlParser: true,
useUnifiedTopology: true,
// Add DataQL configuration
dataql: {
appToken: "your-app-token", // Required for DataQL routing
env: process.env.NODE_ENV === "production" ? "prod" : "dev",
devPrefix: "myapp_", // Optional prefix for dev environments
},
});Examples
Basic CRUD Operations
import { MongoClient } from "@dataql/mongodb-adapter";
async function basicCrud() {
const client = new MongoClient("mongodb://localhost:27017");
await client.connect();
const db = client.db("myapp");
const users = db.collection("users");
// Create
const user = await users.insertOne({
name: "Alice Johnson",
email: "[email protected]",
age: 28,
});
// Read
const foundUser = await users.findOne({ _id: user.insertedId });
// Update
await users.updateOne({ _id: user.insertedId }, { $set: { age: 29 } });
// Delete
await users.deleteOne({ _id: user.insertedId });
await client.close();
}Advanced Queries
async function advancedQueries() {
const client = new MongoClient("mongodb://localhost:27017");
await client.connect();
const db = client.db("ecommerce");
const products = db.collection("products");
// Complex query with multiple conditions
const results = await products
.find({
category: "electronics",
price: { $gte: 100, $lte: 1000 },
inStock: true,
})
.sort({ price: -1 })
.limit(20)
.project({ name: 1, price: 1, rating: 1 })
.toArray();
console.log("Products:", results);
await client.close();
}Bulk Operations
async function bulkOperations() {
const client = new MongoClient("mongodb://localhost:27017");
await client.connect();
const db = client.db("inventory");
const items = db.collection("items");
const operations = [
{
insertOne: {
document: {
sku: "ABC123",
name: "Widget",
quantity: 100,
},
},
},
{
updateOne: {
filter: { sku: "DEF456" },
update: { $inc: { quantity: -5 } },
upsert: true,
},
},
{
deleteOne: {
filter: { quantity: { $lte: 0 } },
},
},
];
const result = await items.bulkWrite(operations);
console.log("Bulk result:", result);
await client.close();
}Limitations
While the adapter provides comprehensive MongoDB API compatibility, some advanced features have limitations:
- Aggregation Pipeline: Basic support only - complex aggregations may not work as expected
- Transactions: Not supported (DataQL handles consistency differently)
- GridFS: Not supported
- Change Streams: Not supported (DataQL provides real-time updates differently)
- Text Search: Limited support
- Geospatial Queries: Limited support
DataQL Benefits
By using this adapter, you get all the benefits of DataQL:
- Offline-First: Your app works without internet connection
- Real-Time Sync: Automatic data synchronization across devices
- Automatic Scaling: No need to manage database infrastructure
- Type Safety: Full TypeScript support with schema validation
- Zero Latency: Local-first architecture for instant responses
Support
License
MIT
