monSQLize 链式调用方法支持文档
📑 目录
�📋 概述
本文档总结 monSQLize 项目中 find 和 aggregate 方法目前支持的原生 MongoDB 链式调用方法。
更新日期: 2025-11-12
版本: v2.0.0 - ✨ 完整链式调用支持
🎉 重大更新
v2.0.0 现已支持完整的 MongoDB 链式调用 API!
现在您可以像使用原生 MongoDB 驱动一样,使用链式调用方法构建查询。所有新的链式方法都完全支持缓存、参数验证和错误处理。
🎯 支持的链式调用方法(已完整实现)
1. find() 方法
✅ 已支持的链式调用(共 12 个方法)
📝 使用示例
// 基础用法 - limit 和 skip
const results = await collection('products')
.find({ category: 'electronics' })
.limit(10)
.skip(5);
// 排序查询
const results = await collection('products')
.find({ inStock: true })
.sort({ price: -1 })
.limit(10);
// 字段投影
const results = await collection('products')
.find({ category: 'books' })
.project({ name: 1, price: 1 })
.limit(5);
// 复杂组合 - 多个链式方法
const results = await collection('products')
.find({ category: 'electronics', inStock: true })
.sort({ rating: -1, sales: -1 })
.skip(5)
.limit(10)
.project({ name: 1, price: 1 })
.hint({ category: 1, price: -1 })
.maxTimeMS(5000)
.comment('复杂查询');
// 查询执行计划
const plan = await collection('products')
.find({ category: 'electronics' })
.sort({ price: -1 })
.limit(10)
.explain('executionStats');
// 流式查询
const stream = collection('products')
.find({ category: 'books' })
.sort({ createdAt: -1 })
.limit(100)
.stream();
2. aggregate() 方法
✅ 已支持的链式调用(共 9 个方法)
📝 使用示例
// 基础聚合
const results = await collection('orders')
.aggregate([
{ $match: { status: 'paid' } },
{ $group: { _id: '$category', total: { $sum: '$amount' } } }
])
.allowDiskUse(true);
// 完整链式调用
const results = await collection('orders')
.aggregate([
{ $match: { status: 'paid' } },
{ $group: { _id: '$category', total: { $sum: '$amount' } } },
{ $sort: { total: -1 } }
])
.hint({ status: 1, createdAt: -1 })
.allowDiskUse(true)
.maxTimeMS(10000)
.comment('分类销售统计');
// 聚合执行计划
const plan = await collection('orders')
.aggregate([
{ $match: { status: 'paid' } },
{ $group: { _id: '$customerId', total: { $sum: '$amount' } } }
])
.explain('executionStats');
// 流式聚合
const stream = collection('orders')
.aggregate([
{ $match: { status: 'paid' } },
{ $limit: 100 }
])
.stream();
🆚 MongoDB 原生链式方法对比
完整对比表
总结: monSQLize v2.0 现已支持绝大部分 MongoDB 原生链式方法(12/17),覆盖了 99% 的日常使用场景。
✨ 新功能亮点
1. Promise 兼容性
链式调用对象实现了完整的 Promise 接口:
// 直接 await
const results = await collection('products').find({}).limit(10);
// 使用 .then()
collection('products')
.find({}).limit(10)
.then(results => console.log(results));
// 使用 .catch()
const results = await collection('products')
.find({}).limit(10)
.catch(err => []);
2. 参数自动验证
// ✅ 正确
.limit(10)
.skip(5)
// ❌ 错误 - 自动抛出异常
.limit(-1) // Error: limit() requires a non-negative number
.skip("invalid") // Error: skip() requires a non-negative number
.sort("invalid") // Error: sort() requires an object or array
3. 执行保护
防止意外的重复执行:
const chain = collection('products').find({}).limit(5);
// 第一次执行 ✅
await chain.toArray();
// 第二次执行 ❌ 抛出错误
await chain.toArray(); // Error: Query already executed
4. 完整缓存支持
链式调用与 options 参数使用相同的缓存键:
// 这两种方式共享缓存
await collection('products').find({}).limit(10).sort({ price: -1 });
await collection('products').find({}, { limit: 10, sort: { price: -1 } });
🔄 向后兼容性
100% 向后兼容
所有现有代码无需修改:
// 旧代码 - 继续工作 ✅
const results = await collection('products').find(
{ category: 'electronics' },
{ limit: 10, sort: { price: -1 } }
);
// 新代码 - 链式调用 ✅
const results = await collection('products')
.find({ category: 'electronics' })
.limit(10)
.sort({ price: -1 });
自动检测
monSQLize 会自动检测调用方式:
- 无 options 参数 → 返回链式构建器
- 有 options 参数 → 直接执行查询
📚 相关文档
📄 更新日志
反馈与建议: 如有问题或建议,请提交 GitHub Issue。
{ $match: { status: 'paid', createdAt: { $gte: new Date('2024-01-01') } } },
{ $group: { _id: '$category', total: { $sum: '$amount' } } },
{ $sort: { total: -1 } }
]).explain('executionStats');
// 指定详细级别 - allPlansExecution
const allPlans = await collection('orders').aggregate([
{ $match: { status: 'paid' } },
{ $sort: { createdAt: -1 } },
{ $limit: 100 }
]).explain('allPlansExecution');
#### 🔍 verbosity 参数说明
与 `find()` 方法完全一致,支持相同的 3 种详细级别。
#### ⚠️ 注意事项
1. **链式调用 vs options 参数**
```javascript
// 链式调用 - 语法简洁
await collection('orders').aggregate(pipeline).explain('executionStats');
// options 参数 - 支持更多聚合选项
await collection('orders').aggregate(pipeline, {
allowDiskUse: true,
maxTimeMS: 5000,
hint: { status: 1, createdAt: -1 },
explain: 'executionStats'
});
🚫 MongoDB 原生链式方法对比
MongoDB 原生 Cursor 链式方法
MongoDB 原生 Cursor 对象支持多种链式调用方法,但 monSQLize 当前仅实现了 .explain() 方法。
📌 设计理念
为什么 monSQLize 不支持完整的链式调用?
-
简化 API 设计
- monSQLize 是多数据库统一读 API,目标是提供简洁一致的接口
- 完整的链式调用会增加实现复杂度和维护成本
-
缓存优先架构
- monSQLize 核心特性是智能缓存(
cache 选项)
- 链式调用的延迟执行与缓存机制难以兼容
- 通过
options 参数一次性传递所有选项,便于缓存键生成
-
Promise 优先返回
- monSQLize 默认返回
Promise<Array>,而非 MongoDB Cursor
- 用户可直接
await 获取结果,无需调用 .toArray()
- 如需流式处理,使用
{ stream: true } 选项
-
保留核心诊断能力
.explain() 是性能诊断的核心方法,因此被单独实现为链式调用
- 与 MongoDB 原生 API 保持一致,降低学习成本
🔧 替代方案
如何实现 MongoDB 原生链式方法的功能?
流式处理示例
// MongoDB 原生方式
const cursor = collection.find({ status: 'active' });
await cursor.forEach(doc => console.log(doc));
// monSQLize 方式
const stream = collection('users').find({ status: 'active' }, { stream: true });
stream.on('data', doc => console.log(doc));
stream.on('end', () => console.log('完成'));
📚 相关文档
🔮 未来规划
可能增加的链式调用支持
基于用户反馈和使用场景,未来可能考虑增加以下链式方法:
-
.toArray()
- 显式转换为数组,与 MongoDB 原生 API 保持一致
- 优先级:🟡 中等(当前默认返回 Promise,已满足大部分需求)
-
.count()
- 直接在查询结果上计数
- 优先级:🟢 低(已有独立的
count() 方法)
-
.forEach(fn) / .map(fn)
- 便捷的遍历和转换方法
- 优先级:🟢 低(使用
{ stream: true } 替代)
-
.limit() / .skip() / .sort()
- 完整的链式查询构建
- 优先级:🔴 低(与缓存架构冲突,不推荐实现)
📞 反馈与建议
如果您在使用过程中有以下需求:
- 需要更多的链式调用支持
- 发现链式调用的 bug 或不一致行为
- 对 API 设计有改进建议
请通过以下方式反馈:
📄 更新日志