Thin MongoDB ODM built for Standard Schema
mongodb zod deno
at main 3.1 kB view raw
1import { z } from "@zod/zod"; 2import { MongoMemoryServer } from "mongodb-memory-server-core"; 3import mongoose from "mongoose"; 4import { connect, disconnect, Model } from "../mod.ts"; 5 6/** 7 * Benchmark basic CRUD operations for Nozzle vs Mongoose. 8 * 9 * Run with: 10 * deno bench -A bench/nozzle_vs_mongoose.bench.ts 11 */ 12 13const userSchema = z.object({ 14 name: z.string(), 15 email: z.string().email(), 16 age: z.number().int().positive().optional(), 17 createdAt: z.date().default(() => new Date()), 18}); 19 20const mongoServer = await MongoMemoryServer.create(); 21const uri = mongoServer.getUri(); 22 23// Use separate DBs to avoid any cross-driver interference 24const nozzleDbName = "bench_nozzle"; 25const mongooseDbName = "bench_mongoose"; 26 27await connect(uri, nozzleDbName); 28const NozzleUser = new Model("bench_users_nozzle", userSchema); 29 30const mongooseConn = await mongoose.connect(uri, { dbName: mongooseDbName }); 31const mongooseUserSchema = new mongoose.Schema( 32 { 33 name: String, 34 email: String, 35 age: Number, 36 createdAt: { type: Date, default: Date.now }, 37 }, 38 { collection: "bench_users_mongoose" }, 39); 40const MongooseUser = mongooseConn.models.BenchUser || 41 mongooseConn.model("BenchUser", mongooseUserSchema); 42 43// Start from a clean state 44await NozzleUser.delete({}); 45await MongooseUser.deleteMany({}); 46 47// Seed base documents for read/update benches 48const nozzleSeed = await NozzleUser.insertOne({ 49 name: "Seed Nozzle", 50 email: "seed-nozzle@example.com", 51 age: 30, 52}); 53const mongooseSeed = await MongooseUser.create({ 54 name: "Seed Mongoose", 55 email: "seed-mongoose@example.com", 56 age: 30, 57}); 58 59const nozzleSeedId = nozzleSeed.insertedId; 60const mongooseSeedId = mongooseSeed._id; 61 62let counter = 0; 63const nextEmail = (prefix: string) => `${prefix}-${counter++}@bench.dev`; 64 65Deno.bench("mongoose insertOne", { group: "insertOne" }, async () => { 66 await MongooseUser.insertOne({ 67 name: "Mongoose User", 68 email: nextEmail("mongoose"), 69 age: 25, 70 }); 71}); 72 73Deno.bench( 74 "nozzle insertOne", 75 { group: "insertOne", baseline: true }, 76 async () => { 77 await NozzleUser.insertOne({ 78 name: "Nozzle User", 79 email: nextEmail("nozzle"), 80 age: 25, 81 }); 82 }, 83); 84 85Deno.bench("mongoose findById", { group: "findById" }, async () => { 86 await MongooseUser.findById(mongooseSeedId); 87}); 88 89Deno.bench( 90 "nozzle findById", 91 { group: "findById", baseline: true }, 92 async () => { 93 await NozzleUser.findById(nozzleSeedId); 94 }, 95); 96 97Deno.bench("mongoose updateOne", { group: "updateOne" }, async () => { 98 await MongooseUser.updateOne( 99 { _id: mongooseSeedId }, 100 { $set: { age: 31 } }, 101 ); 102}); 103 104Deno.bench( 105 "nozzle updateOne", 106 { group: "updateOne", baseline: true }, 107 async () => { 108 await NozzleUser.updateOne( 109 { _id: nozzleSeedId }, 110 { age: 31 }, 111 ); 112 }, 113); 114 115// Attempt graceful shutdown when the process exits 116async function cleanup() { 117 await disconnect(); 118 await mongooseConn.disconnect(); 119 await mongoServer.stop(); 120} 121 122globalThis.addEventListener("unload", () => { 123 void cleanup(); 124});