Skip to content

Commit 24d5ef5

Browse files
committed
feat:大规模重构兼容原生写法
1 parent cf603dd commit 24d5ef5

48 files changed

Lines changed: 7863 additions & 2241 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CHANGELOG.md‎

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,86 @@
44

55
## [未发布]
66

7+
### Changed
8+
- **explain 示例和测试更新**(2025-11-12)
9+
- `examples/explain.examples.js`:所有示例从旧版 `explain({ query, verbosity })` 改为原生风格 `find(filter, { explain })`
10+
- 示例 1-5 全部更新为使用 options 参数的方式
11+
- 保持与 MongoDB 原生 API 完全一致的调用风格
12+
13+
- **explain 链式调用支持**(2025-11-12)
14+
- ✨ 新增链式调用支持:
15+
- `collection.find({ ... }).explain('executionStats')`
16+
- `collection.aggregate([...]).explain('executionStats')`
17+
- 完全兼容原生 MongoDB 的链式调用语法
18+
- 通过在 Promise 上添加 explain() 方法实现
19+
- 同时保留 options 参数方式:
20+
- `find(filter, { explain: 'executionStats' })`
21+
- `aggregate(pipeline, { explain: 'executionStats' })`
22+
- ❌ 删除独立 explain 方法:`collection.explain({ query, verbosity })`(API 与原生不一致)
23+
- 现在只支持两种方式:链式调用和 options 参数,都与原生 MongoDB 兼容
24+
- 更新所有测试用例,使用新的 API
25+
26+
- **explain 文档重构**(2025-11-12)
27+
- 明确使用原生 MongoDB `Cursor.explain()` 方法
28+
- 支持两种调用方式:链式调用和 options 参数
29+
- 新增与原生 MongoDB 的对比:实现原理和使用示例
30+
- 新增聚合管道的 explain 示例:管道分析、优化建议、阶段性能对比
31+
- 新增常见问题章节:verbosity 选择、性能影响、执行计划解读、索引问题诊断、聚合管道优化
32+
33+
- **distinct 文档重构**(2025-11-12) - 明确使用原生 MongoDB `Collection.distinct()` 方法
34+
- 扩展 options 参数:新增 `session`(事务支持)、`comment`(查询注释)、`collation`(排序规则)等原生选项
35+
- 新增使用模式:事务中的 distinct 查询(第 9 节)
36+
- 新增使用建议章节:何时使用 distinct、性能考虑、缓存策略
37+
- 优化常见问题:新增 Q1(monSQLize 与原生 MongoDB 的区别)、Q7(事务使用)
38+
- 扩展最佳实践:从 7 条增加到 10 条,包含索引优化、缓存策略、事务使用等
39+
40+
- **estimated-count 文档重构**(2025-11-12)
41+
- 明确使用原生 MongoDB `estimatedDocumentCount()` 方法
42+
- 扩展 options 参数:新增 `maxTimeMS`(超时控制)、`comment`(查询注释)等原生选项
43+
- 新增性能对比章节:estimatedDocumentCount vs countDocuments vs count(性能差异对比)
44+
- 新增使用建议章节:何时使用 estimatedDocumentCount、性能考虑
45+
- 优化最佳实践:从简单列表扩展为详细说明,包含具体代码示例
46+
47+
- **count 文档重构**(2025-11-12)
48+
- 明确使用原生 MongoDB `countDocuments()` 方法
49+
- 扩展 options 参数:新增 `skip`、`session`、`hint`、`comment` 等原生选项
50+
- 新增使用模式:事务中的 count 查询、使用 hint 指定索引
51+
- 优化最佳实践:添加具体代码示例和场景说明
52+
53+
- **distinct 方法 API 重构**(2025-11-11)
54+
- 方法签名变更:从 `distinct(field, options)` 改为 `distinct(field, query, options)`,将 query 参数独立出来
55+
- 新增参数支持:`comment`(查询注释,用于日志和性能分析)
56+
- 与 MongoDB 原生 API 保持一致:使用原生 `collection.distinct(field, query, options)` 方法
57+
- 更新文档:`docs/distinct.md` - 反映新的 API 格式和参数说明
58+
- 更新示例:`examples/distinct.examples.js` - 所有 10 个示例迁移到新 API
59+
- ⚠️ **破坏性变更**:不兼容旧版本 `distinct('field', { query: {...} })` 格式,需修改为 `distinct('field', query, options)`
60+
61+
- **count 方法 API 重构**(2025-11-11)
62+
- 使用 MongoDB 原生推荐的 API:`countDocuments()` 和 `estimatedDocumentCount()`
63+
- 方法签名变更:从 `count(options)` 改为 `count(query, options)`,将 query 参数独立出来
64+
- 新增参数支持:`skip`、`limit`(用于分页统计和抽样统计)
65+
- 性能优化:空查询自动使用 `estimatedDocumentCount()`(基于元数据,毫秒级)
66+
- 更新文档:`docs/count.md` - 反映新的 API 格式和参数说明
67+
- 更新示例:`examples/count.examples.js` - 所有示例迁移到新 API
68+
- 创建迁移指南:`docs/count-migration-guide.md` - 帮助用户从旧版本迁移
69+
- ⚠️ **破坏性变更**:不兼容旧版本 `count({ query: {...} })` 格式,需按迁移指南修改代码
70+
71+
- **find 和 findOne 方法 API 重构**(2025-11-12)
72+
- 方法签名变更:从 `find(options)` / `findOne(options)` 改为 `find(query, options)` / `findOne(query, options)`,将 query 参数独立出来
73+
- 与 MongoDB 原生 API 保持一致:使用原生 `collection.find(query, options)` / `collection.findOne(query, options)` 方法
74+
- 更新文档:
75+
- `docs/find.md` - 反映新的 API 格式和参数说明(29 个代码示例全部更新)
76+
- `docs/findOne.md` - 反映新的 API 格式和参数说明(15 个代码示例全部更新)
77+
- `README.md` - 更新所有代码示例(13 个示例)
78+
- 更新示例:
79+
- `examples/find.examples.js` - 所有 10 个示例迁移到新 API
80+
- `examples/findOne.examples.js` - 所有 7 个示例迁移到新 API
81+
- 更新 TypeScript 定义:
82+
- `index.d.ts` - 更新方法签名和接口定义
83+
- 移除 `FindOptions.query` 字段
84+
- 所有方法签名(find/findOne/count/distinct/stream/explain)改为两参数形式
85+
- ⚠️ **破坏性变更**:不兼容旧版本 `find({ query: {...} })` 格式,需修改为 `find(query, options)`
86+
787
### 新增
888
- **insertOne 和 insertMany 写操作文档补充**(2025-11-10)
989
- README.md:添加"写入操作"表格和详细使用示例(第 8 节)

‎README.md‎

Lines changed: 95 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -46,27 +46,33 @@ const MonSQLize = require('monsqlize');
4646
}).connect();
4747

4848
// 查询单个文档
49-
const one = await collection('test').findOne({
50-
query: { status: 'active' },
51-
cache: 5000, // 缓存 5 秒
52-
maxTimeMS: 1500 // 覆盖全局超时
53-
});
49+
const one = await collection('test').findOne(
50+
{ status: 'active' },
51+
{
52+
cache: 5000, // 缓存 5 秒
53+
maxTimeMS: 1500 // 覆盖全局超时
54+
}
55+
);
5456
console.log('findOne ->', one);
5557

5658
// 查询多个文档
57-
const list = await collection('test').find({
58-
query: { category: 'electronics' },
59-
limit: 10, // 限制 10 条
60-
cache: 3000 // 缓存 3 秒
61-
});
59+
const list = await collection('test').find(
60+
{ category: 'electronics' },
61+
{
62+
limit: 10, // 限制 10 条
63+
cache: 3000 // 缓存 3 秒
64+
}
65+
);
6266
console.log('find ->', list.length);
6367

6468
// 跨库访问
65-
const event = await db('analytics').collection('events').findOne({
66-
query: { type: 'click' },
67-
cache: 3000,
68-
maxTimeMS: 1500
69-
});
69+
const event = await db('analytics').collection('events').findOne(
70+
{ type: 'click' },
71+
{
72+
cache: 3000,
73+
maxTimeMS: 1500
74+
}
75+
);
7076
console.log('跨库查询 ->', event);
7177
})();
7278
```
@@ -138,22 +144,26 @@ const MonSQLize = require('monsqlize');
138144

139145
```js
140146
// 数组模式(默认)
141-
const products = await collection('products').find({
142-
query: { category: 'electronics', inStock: true },
143-
projection: { name: 1, price: 1 },
144-
sort: { price: -1 },
145-
limit: 20,
146-
cache: 5000,
147-
comment: 'ProductAPI:listProducts:user_123' // 生产环境日志跟踪(可选)
148-
});
147+
const products = await collection('products').find(
148+
{ category: 'electronics', inStock: true },
149+
{
150+
projection: { name: 1, price: 1 },
151+
sort: { price: -1 },
152+
limit: 20,
153+
cache: 5000,
154+
comment: 'ProductAPI:listProducts:user_123' // 生产环境日志跟踪(可选)
155+
}
156+
);
149157

150158
// 流式传输(大数据量)
151-
const stream = await collection('products').find({
152-
query: { category: 'electronics' },
153-
stream: true, // 返回流
154-
cache: 0, // 禁用缓存
155-
comment: 'ExportService:streamProducts' // 标识查询来源
156-
});
159+
const stream = await collection('products').find(
160+
{ category: 'electronics' },
161+
{
162+
stream: true, // 返回流
163+
cache: 0, // 禁用缓存
164+
comment: 'ExportService:streamProducts' // 标识查询来源
165+
}
166+
);
157167

158168
stream.on('data', (doc) => {
159169
console.log('处理文档:', doc);
@@ -172,34 +182,40 @@ stream.on('end', () => {
172182

173183
```js
174184
// 游标分页(推荐)
175-
const page1 = await collection('products').findPage({
176-
query: { category: 'electronics' },
177-
limit: 20,
178-
sort: { createdAt: -1 },
179-
bookmarks: {
180-
step: 10, // 每 10 页缓存一个书签
181-
maxHops: 20, // 最多跳跃 20 次
182-
ttlMs: 3600000 // 书签缓存 1 小时
185+
const page1 = await collection('products').findPage(
186+
{ category: 'electronics' },
187+
{
188+
limit: 20,
189+
sort: { createdAt: -1 },
190+
bookmarks: {
191+
step: 10, // 每 10 页缓存一个书签
192+
maxHops: 20, // 最多跳跃 20 次
193+
ttlMs: 3600000 // 书签缓存 1 小时
194+
}
183195
}
184-
});
196+
);
185197

186198
console.log('第 1 页:', page1.data);
187199
console.log('下一页游标:', page1.cursor);
188200

189201
// 使用游标获取下一页
190-
const page2 = await collection('products').findPage({
191-
query: { category: 'electronics' },
192-
limit: 20,
193-
cursor: page1.cursor // 传入上一页的游标
194-
});
202+
const page2 = await collection('products').findPage(
203+
{ category: 'electronics' },
204+
{
205+
limit: 20,
206+
cursor: page1.cursor // 传入上一页的游标
207+
}
208+
);
195209

196210
// 跳页模式(跳到第 100 页)
197-
const page100 = await collection('products').findPage({
198-
query: { category: 'electronics' },
199-
limit: 20,
200-
page: 100, // 跳到第 100 页
201-
bookmarks: { step: 10, maxHops: 20, ttlMs: 3600000 }
202-
});
211+
const page100 = await collection('products').findPage(
212+
{ category: 'electronics' },
213+
{
214+
limit: 20,
215+
page: 100, // 跳到第 100 页
216+
bookmarks: { step: 10, maxHops: 20, ttlMs: 3600000 }
217+
}
218+
);
203219
```
204220

205221
**详细文档**: [docs/findPage.md](./docs/findPage.md)
@@ -248,11 +264,13 @@ const msq = new MonSQLize({
248264
});
249265

250266
// 查询级缓存
251-
const products = await collection('products').find({
252-
query: { category: 'electronics' },
253-
cache: 5000, // 缓存 5 秒
254-
maxTimeMS: 3000
255-
});
267+
const products = await collection('products').find(
268+
{ category: 'electronics' },
269+
{
270+
cache: 5000, // 缓存 5 秒
271+
maxTimeMS: 3000
272+
}
273+
);
256274

257275
// 获取缓存统计
258276
const stats = msq.getCacheStats();
@@ -284,10 +302,12 @@ const msq = new MonSQLize({
284302
const { db, collection } = await msq.connect();
285303

286304
// 跨库访问
287-
const analyticsEvent = await db('analytics').collection('events').findOne({
288-
query: { type: 'click' },
289-
cache: 3000
290-
});
305+
const analyticsEvent = await db('analytics').collection('events').findOne(
306+
{ type: 'click' },
307+
{
308+
cache: 3000
309+
}
310+
);
291311

292312
// 关闭连接
293313
await msq.close();
@@ -314,9 +334,9 @@ await msq.connect();
314334
const { collection } = msq;
315335

316336
// 所有查询自动从从节点读取(降低主节点负载)
317-
const products = await collection('products').find({
318-
query: { category: 'electronics' }
319-
});
337+
const products = await collection('products').find(
338+
{ category: 'electronics' }
339+
);
320340

321341
console.log(`✅ 从从节点读取 ${products.length} 条数据`);
322342
```
@@ -436,18 +456,22 @@ const msq = new MonSQLize({
436456
const { collection } = await msq.connect();
437457

438458
// 第 1 次查询:缓存 miss → 查询 MongoDB → 存入本地 + Redis
439-
const products1 = await collection('products').find({
440-
query: { category: 'electronics' },
441-
cache: 10000, // 缓存 10 秒
442-
maxTimeMS: 3000
443-
});
459+
const products1 = await collection('products').find(
460+
{ category: 'electronics' },
461+
{
462+
cache: 10000, // 缓存 10 秒
463+
maxTimeMS: 3000
464+
}
465+
);
444466

445467
// 第 2 次查询:本地缓存命中(0.001ms)
446-
const products2 = await collection('products').find({
447-
query: { category: 'electronics' },
448-
cache: 10000,
449-
maxTimeMS: 3000
450-
});
468+
const products2 = await collection('products').find(
469+
{ category: 'electronics' },
470+
{
471+
cache: 10000,
472+
maxTimeMS: 3000
473+
}
474+
);
451475

452476
// 如果本地缓存过期,但 Redis 还有 → 从 Redis 读取(1-2ms)并回填本地
453477
```

0 commit comments

Comments
 (0)