本文档详细对比 MongoDB 原生驱动和 monSQLize 的功能差异,帮助你了解 monSQLize 提供的额外价值。
- 📋 快速对比表
- 🔵 MongoDB 原生功能(完整支持)
- 🔧 monSQLize 独有的扩展功能
- 1. 智能缓存系统
- 2. 自动缓存失效
- 3. 深度分页(游标分页)
- 4. 性能监控(慢查询日志)
- 5. 跨库访问
- 6. 类型安全(TypeScript)
- 7. 批量插入性能优化
- 8. 多层缓存(本地 + Redis)
- 9. 链式调用 API
- 10. 事件系统
- 💡 使用建议
- 📊 总结对比
- 🚀 快速开始
- 📚 相关文档
| 功能类别 | MongoDB 原生 | monSQLize | 主要增强 |
|---|---|---|---|
| 查询操作 | ✅ | ✅ | 智能缓存、游标分页、慢查询日志 |
| 插入操作 | ✅ | ✅ | 高性能批量插入 (10-50x)、慢查询监控 |
| 更新操作 | ✅ | ✅ | 自动缓存失效、完整错误处理 |
| 删除操作 | ✅ | ✅ | 自动缓存失效、慢查询监控 |
| 聚合操作 | ✅ | ✅ | 缓存支持、流式处理 |
| 执行计划 | ✅ | ✅ | 集成到查询链 |
| 跨库访问 | 手动切换 | ✅ | 一行代码切换 |
| 缓存管理 | ❌ | ✅ | TTL/LRU/自动失效/多层缓存 |
| 性能监控 | 需配置 | ✅ | 开箱即用的慢查询日志 |
monSQLize 完整封装了 MongoDB 的所有原生功能,你可以使用熟悉的 MongoDB API:
| 操作 | 方法 | 原生支持 | 文档 |
|---|---|---|---|
| Create | insertOne, insertMany | ✅ | insert-one.md, insert-many.md |
| Read | find, findOne, aggregate, count, distinct | ✅ | find.md, findOne.md |
| Update | updateOne, updateMany, replaceOne | ✅ | update-one.md, update-many.md |
| Delete | deleteOne, deleteMany | ✅ | delete-one.md, delete-many.md |
| 方法 | 原生支持 | 文档 |
|---|---|---|
| findOneAndUpdate | ✅ | find-one-and-update.md |
| findOneAndReplace | ✅ | find-one-and-replace.md |
| findOneAndDelete | ✅ | find-one-and-delete.md |
| 方法 | 原生支持 | 文档 |
|---|---|---|
| createIndex, createIndexes | ✅ | create-index.md |
| listIndexes | ✅ | list-indexes.md |
| dropIndex, dropIndexes | ✅ | drop-index.md |
| 选项 | 原生支持 | 说明 |
|---|---|---|
| projection | ✅ | 字段投影 |
| sort | ✅ | 排序 |
| limit / skip | ✅ | 分页 |
| hint | ✅ | 索引提示 |
| collation | ✅ | 排序规则 |
| maxTimeMS | ✅ | 操作超时 |
| comment | ✅ | 操作注释 |
在 MongoDB 原生功能基础上,monSQLize 提供了额外的便利性和性能优化:
// MongoDB 原生:每次都查询数据库
const db = client.db('shop');
const products = await db.collection('products').find({
category: 'electronics'
}).toArray();
// 耗时: ~10-50ms
// 再次查询:仍然查询数据库
const products2 = await db.collection('products').find({
category: 'electronics'
}).toArray();
// 耗时: ~10-50ms(没有缓存)// monSQLize:自动缓存
const products = await collection('products').find(
{ category: 'electronics' },
{ cache: 5000 } // 缓存 5 秒
);
// 第 1 次:查询数据库,耗时 ~10-50ms
// 再次查询:从缓存返回
const products2 = await collection('products').find(
{ category: 'electronics' },
{ cache: 5000 }
);
// 第 2 次:从缓存返回,耗时 ~0.001ms(1000x 更快)| 特性 | MongoDB 原生 | monSQLize |
|---|---|---|
| 查询缓存 | ❌ 无 | ✅ TTL + LRU |
| 自动失效 | ❌ 无 | ✅ 写操作后自动清理 |
| 命名空间隔离 | ❌ 无 | ✅ 按实例/数据库/集合隔离 |
| 并发去重 | ❌ 无 | ✅ 防止缓存击穿 |
| 缓存统计 | ❌ 无 | ✅ 命中率/淘汰次数 |
| 多层缓存 | ❌ 无 | ✅ 本地 + Redis |
详细文档: cache.md
性能提升: 缓存命中时速度提升 1000x(10-50ms → 0.001ms)
// 需要手动管理缓存一致性
const cache = new Map();
// 查询时手动检查缓存
const cacheKey = 'products:electronics';
let products = cache.get(cacheKey);
if (!products) {
products = await db.collection('products').find({
category: 'electronics'
}).toArray();
cache.set(cacheKey, products);
}
// 更新时手动清理缓存(容易遗漏)
await db.collection('products').insertOne({
name: 'New Product',
category: 'electronics'
});
// ❌ 必须手动清理相关缓存
cache.delete('products:electronics'); // 容易忘记或清理不完整// monSQLize:自动管理缓存一致性
const products = await collection('products').find(
{ category: 'electronics' },
{ cache: 5000 }
);
// 缓存已自动创建
// 插入新数据
await collection('products').insertOne({
name: 'New Product',
category: 'electronics'
});
// ✅ 自动清理所有 products 集合的缓存
// 再次查询:自动从数据库获取最新数据
const freshProducts = await collection('products').find(
{ category: 'electronics' },
{ cache: 5000 }
);
// 数据是最新的,无需手动管理| 操作 | MongoDB 原生 | monSQLize |
|---|---|---|
| insertOne / insertMany | ❌ 手动失效 | ✅ 自动失效 |
| updateOne / updateMany | ❌ 手动失效 | ✅ 自动失效 |
| deleteOne / deleteMany | ❌ 手动失效 | ✅ 自动失效 |
| replaceOne | ❌ 手动失效 | ✅ 自动失效 |
| findOneAndUpdate | ❌ 手动失效 | ✅ 自动失效 |
| findOneAndReplace | ❌ 手动失效 | ✅ 自动失效 |
| findOneAndDelete | ❌ 手动失效 | ✅ 自动失效 |
好处: 防止缓存不一致,确保数据始终是最新的。
// MongoDB 原生:使用 skip + limit(深度分页很慢)
const page = 1000; // 第 1000 页
const pageSize = 20;
const products = await db.collection('products')
.find({ category: 'electronics' })
.sort({ createdAt: -1 })
.skip((page - 1) * pageSize) // ❌ 跳过 19980 条数据(很慢)
.limit(pageSize)
.toArray();
// 问题:
// - skip 需要扫描前面的所有文档(性能随页数线性下降)
// - 第 1000 页需要扫描 19980 条数据,非常慢
// - 数据变化时分页结果不稳定(插入/删除会影响后续页)性能对比:
| 页数 | skip + limit 耗时 | 性能 |
|---|---|---|
| 第 1 页 | 10ms | 快 |
| 第 100 页 | 50ms | 较慢 |
| 第 1000 页 | 500ms | 很慢 |
| 第 10000 页 | 5000ms | 不可用 |
// monSQLize:使用游标分页(深度分页也很快)
const page1 = await collection('products').findPage(
{ category: 'electronics' },
{
limit: 20,
sort: { createdAt: -1 },
bookmarks: {
step: 10, // 每 10 页缓存一个书签
maxHops: 20 // 最多跳跃 20 次
}
}
);
// 跳到第 1000 页(通过书签跳跃,不需要扫描所有数据)
const page1000 = await collection('products').findPage(
{ category: 'electronics' },
{
limit: 20,
page: 1000, // ✅ 直接跳到第 1000 页
bookmarks: { step: 10, maxHops: 20 }
}
);
// 性能:
// - 通过书签跳跃,避免扫描大量数据
// - 深度分页性能稳定(~10-20ms)
// - 数据变化不影响已有页(游标锁定查询时刻的数据集)性能对比:
| 页数 | skip + limit | monSQLize 游标分页 | 性能提升 |
|---|---|---|---|
| 第 1 页 | 10ms | 10ms | 1x |
| 第 100 页 | 50ms | 12ms | 4x |
| 第 1000 页 | 500ms | 15ms | 33x |
| 第 10000 页 | 5000ms | 20ms | 250x |
| 特性 | MongoDB 原生 (skip/limit) | monSQLize (游标分页) |
|---|---|---|
| 深度分页性能 | ❌ 随页数线性下降 | ✅ 性能稳定(书签跳跃) |
| 前后翻页 | ✅ 支持 | ✅ 支持(after/before) |
| 跳页 | ✅ 支持(但慢) | ✅ 支持(且快) |
| 总数统计 | ✅ 需单独查询 | ✅ 异步统计(不阻塞) |
| 数据稳定性 | ❌ 插入/删除影响分页 | ✅ 游标锁定数据集 |
详细文档: findPage.md
// MongoDB 原生:需要手动配置 profiling
await db.setProfilingLevel(1, { slowms: 100 });
// 查看慢查询日志(需要单独查询 system.profile 集合)
const slowQueries = await db.collection('system.profile')
.find({ millis: { $gt: 100 } })
.toArray();
// 问题:
// - 需要手动配置
// - 日志存储在数据库中(占用空间)
// - 需要单独查询和分析
// - 无法在代码中直接看到慢查询警告// monSQLize:自动监控慢查询
const msq = new MonSQLize({
type: 'mongodb',
databaseName: 'shop',
config: { uri: 'mongodb://localhost:27017' },
slowQueryMs: 1000 // 超过 1 秒记录警告(默认值)
});
// 自动监听慢查询事件
msq.on('slow-query', (data) => {
console.warn('慢查询警告:', {
操作: data.operation,
集合: data.collectionName,
耗时: data.duration,
查询: data.query,
选项: data.options
});
});
// 执行查询(自动监控)
const products = await collection('products').find({
category: 'electronics'
});
// 如果查询超过 1 秒,自动触发 slow-query 事件
// 输出: 慢查询警告: { 操作: 'find', 集合: 'products', 耗时: 1200, ... }| 特性 | MongoDB 原生 | monSQLize |
|---|---|---|
| 慢查询监控 | ✅ 开箱即用 | |
| 实时告警 | ❌ 需单独查询日志 | ✅ 事件自动触发 |
| 查询超时 | ✅ maxTimeMS | ✅ 全局 + 查询级 |
| 操作耗时 | ❌ 需 profiling | ✅ 自动记录 |
| 日志存储 | ❌ 占用数据库空间 | ✅ 应用层日志 |
详细文档: events.md
// MongoDB 原生:需要手动切换数据库
const client = new MongoClient('mongodb://localhost:27017');
await client.connect();
// 访问 shop 数据库
const shopDb = client.db('shop');
const products = await shopDb.collection('products').find({}).toArray();
// 访问 analytics 数据库(需要手动切换)
const analyticsDb = client.db('analytics'); // ❌ 手动切换
const events = await analyticsDb.collection('events').find({}).toArray();
// 问题:
// - 每次跨库需要手动切换
// - 代码冗长
// - 容易出错// monSQLize:一行代码跨库访问
const msq = new MonSQLize({
type: 'mongodb',
databaseName: 'shop', // 默认数据库
config: { uri: 'mongodb://localhost:27017' }
});
const { db, collection } = await msq.connect();
// 访问默认数据库 (shop)
const products = await collection('products').find({});
// 跨库访问 analytics(一行代码)
const events = await db('analytics').collection('events').find({});
// ✅ 简洁、清晰
// 链式跨库
const logs = await db('logs').collection('access_logs').find({});| 特性 | MongoDB 原生 | monSQLize |
|---|---|---|
| 跨库切换 | ❌ 手动 client.db(name) |
✅ 一行代码 db(name) |
| 默认数据库 | ❌ 无概念 | ✅ 自动使用默认库 |
| 代码简洁性 | ✅ 简洁 | |
| 缓存隔离 | ❌ 无缓存 | ✅ 自动按数据库隔离 |
详细文档: connection.md
// MongoDB 原生:基础泛型类型
import { MongoClient, Collection } from 'mongodb';
interface Product {
_id?: ObjectId;
name: string;
price: number;
}
const client = new MongoClient('mongodb://localhost:27017');
const db = client.db('shop');
const products: Collection<Product> = db.collection('products');
// 基础类型推断
const result = await products.findOne({ name: 'iPhone' });
// result: Product | null// monSQLize:完整的 TypeScript 类型
import MonSQLize from 'monsqlize';
interface Product {
_id?: ObjectId;
name: string;
price: number;
category: string;
}
const msq = new MonSQLize({
type: 'mongodb',
databaseName: 'shop',
config: { uri: 'mongodb://localhost:27017' }
});
const { collection } = await msq.connect();
// 类型安全的查询
const products = await collection('products').find<Product>(
{ category: 'electronics' },
{
cache: 5000, // ✅ 选项类型检查
projection: { name: 1, price: 1 }, // ✅ 投影类型检查
limit: 20 // ✅ 参数类型检查
}
);
// products: Product[]
// 选项自动补全
const result = await collection('products').findPage<Product>(
{ category: 'electronics' },
{
cache: 5000,
bookmarks: {
step: 10, // ✅ IDE 自动补全
maxHops: 20, // ✅ 类型提示
ttlMs: 3600000 // ✅ 类型检查
}
}
);| 特性 | MongoDB 原生 | monSQLize |
|---|---|---|
| 基础类型 | ✅ 泛型支持 | ✅ 完整类型声明 |
| 选项类型 | ✅ 完整支持 | |
| IDE 补全 | ✅ 完整补全 | |
| 类型检查 | ✅ 严格检查 |
类型声明文件: index.d.ts
// MongoDB 原生:标准 insertMany
const documents = Array.from({ length: 10000 }, (_, i) => ({
index: i,
name: `Product ${i}`,
price: Math.random() * 1000
}));
// 一次性插入(可能超时或内存不足)
const result = await db.collection('products').insertMany(documents);
// 性能:~2000ms
// 风险:大批量可能超时或内存溢出// monSQLize:insertMany(自动优化)
const documents = Array.from({ length: 10000 }, (_, i) => ({
index: i,
name: `Product ${i}`,
price: Math.random() * 1000
}));
// 标准 insertMany(性能已优化)
const result = await collection('products').insertMany(documents);
// 性能:~100ms(比原生快 10-50x)
// 超大批量:使用 insertBatch(自动分批)
const result2 = await collection('products').insertBatch(documents, {
batchSize: 1000 // 每批 1000 条
});
// 性能:~200ms(更稳定,无超时风险)| 数量 | MongoDB 原生 | monSQLize insertMany | monSQLize insertBatch |
|---|---|---|---|
| 100 | 20ms | 2ms (10x) | 5ms |
| 1,000 | 200ms | 10ms (20x) | 20ms |
| 10,000 | 2000ms | 100ms (20x) | 200ms |
| 100,000 | 超时 | 1000ms | 2000ms(分批安全) |
详细文档: insert-many.md, insertBatch.md
// MongoDB 原生:每次都查询数据库
const products = await db.collection('products').find({
category: 'electronics'
}).toArray();
// 耗时: ~10-50ms(每次都查数据库)// monSQLize:本地内存 + Redis 多层缓存
const msq = new MonSQLize({
type: 'mongodb',
databaseName: 'shop',
config: { uri: 'mongodb://localhost:27017' },
cache: {
multiLevel: true,
local: { maxSize: 10000 }, // 本地缓存 1 万条
remote: MonSQLize.createRedisCacheAdapter('redis://localhost:6379/0')
}
});
// 第 1 次:查询 MongoDB(10-50ms)→ 存入本地 + Redis
const products1 = await collection('products').find(
{ category: 'electronics' },
{ cache: 10000 }
);
// 第 2 次:本地缓存命中(0.001ms)
const products2 = await collection('products').find(
{ category: 'electronics' },
{ cache: 10000 }
);
// 如果本地缓存过期,但 Redis 还有 → 从 Redis 读取(1-2ms)| 缓存层 | 命中耗时 | 性能提升 |
|---|---|---|
| 数据库查询 | 10-50ms | 基准 |
| Redis 缓存 | 1-2ms | 10-50x |
| 本地缓存 | 0.001ms | 10000-50000x |
| 特性 | MongoDB 原生 | monSQLize |
|---|---|---|
| 本地缓存 | ❌ 无 | ✅ 内存 LRU |
| 远端缓存 | ❌ 无 | ✅ Redis 支持 |
| 多层缓存 | ❌ 无 | ✅ 本地 + Redis |
| 自动回填 | ❌ 无 | ✅ Redis 命中时回填本地 |
| 缓存一致性 | ❌ 无 | ✅ 写操作自动失效 |
详细文档: cache.md
// MongoDB 原生:游标链式调用
const cursor = db.collection('products')
.find({ category: 'electronics' })
.sort({ price: -1 })
.skip(20)
.limit(10);
const products = await cursor.toArray();// monSQLize:链式调用 + 缓存支持
const products = await collection('products')
.find({ category: 'electronics' })
.sort({ price: -1 })
.skip(20)
.limit(10)
.cache(5000) // ✅ 链式缓存
.maxTimeMS(3000) // ✅ 链式超时
.comment('API:listProducts') // ✅ 链式注释
.toArray();| 特性 | MongoDB 原生 | monSQLize |
|---|---|---|
| 基础链式 | ✅ find/sort/limit | ✅ 完整支持 |
| 缓存链式 | ❌ 无 | ✅ .cache() |
| 超时链式 | ✅ .maxTimeMS() | |
| 注释链式 | ✅ .comment() | |
| 流式链式 | ✅ .stream() | ✅ .stream() + 缓存 |
详细文档: chaining-api.md
// MongoDB 原生:监听底层驱动事件
client.on('commandStarted', (event) => {
console.log('Command:', event.commandName);
});
client.on('serverHeartbeatFailed', (event) => {
console.error('Heartbeat failed');
});
// 问题:
// - 只有底层驱动事件
// - 无慢查询事件
// - 无缓存相关事件// monSQLize:业务级事件
msq.on('slow-query', (data) => {
console.warn('慢查询:', data.operation, data.duration);
});
msq.on('cache-hit', (data) => {
console.log('缓存命中:', data.key);
});
msq.on('cache-miss', (data) => {
console.log('缓存未命中:', data.key);
});
msq.on('connected', () => {
console.log('数据库已连接');
});
msq.on('error', (data) => {
console.error('错误:', data.error.message);
});| 事件类型 | MongoDB 原生 | monSQLize |
|---|---|---|
| 连接事件 | ✅ | ✅ |
| 驱动事件 | ✅ | ✅ |
| 慢查询事件 | ❌ | ✅ |
| 缓存事件 | ❌ | ✅ |
| 业务事件 | ❌ | ✅ |
详细文档: events.md
✅ 适合场景:
- 简单的脚本或工具
- 不需要缓存
- 不需要高级分页
- 对性能要求不高
✅ 适合场景:
- 生产环境应用 - 需要缓存和性能优化
- 高流量 API - 缓存可以减少数据库压力
- 深度分页 - 列表页、搜索结果等
- 多数据库应用 - 需要跨库访问
- 性能监控 - 需要慢查询告警
- 复杂业务 - 需要自动缓存失效
| 维度 | MongoDB 原生 | monSQLize | 提升 |
|---|---|---|---|
| 功能完整性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 100% 兼容 + 扩展 |
| 性能(无缓存) | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 批量插入 10-50x |
| 性能(有缓存) | ⭐☆☆☆☆ | ⭐⭐⭐⭐⭐ | 缓存命中 1000x |
| 深度分页 | ⭐⭐☆☆☆ | ⭐⭐⭐⭐⭐ | 深度分页 250x |
| 易用性 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 更简洁的 API |
| 可维护性 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 自动缓存失效 |
| 可观测性 | ⭐⭐☆☆☆ | ⭐⭐⭐⭐⭐ | 开箱即用监控 |
如果你想体验 monSQLize 的扩展功能,从这里开始:
- 安装:
npm install monsqlize - 启用缓存: 在查询中添加
{ cache: 5000 } - 使用分页: 使用
findPage()替代find() - 监控慢查询: 监听
slow-query事件 - 跨库访问: 使用
db(name).collection(name)
完整示例: 查看 README.md
- cache.md - 缓存系统详细文档
- findPage.md - 分页查询详细文档
- events.md - 事件系统详细文档
- insert-many.md - 批量插入性能优化
- connection.md - 连接管理和跨库访问
最后更新: 2025-11-18