monsqlize 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +91 -2471
- package/README.md +641 -1217
- package/index.d.ts +252 -15
- package/lib/cache.js +8 -8
- package/lib/common/validation.js +64 -1
- package/lib/connect.js +3 -3
- package/lib/errors.js +10 -0
- package/lib/index.js +118 -9
- package/lib/infrastructure/ssh-tunnel-ssh2.js +211 -0
- package/lib/infrastructure/ssh-tunnel.js +40 -0
- package/lib/infrastructure/uri-parser.js +35 -0
- package/lib/lock/Lock.js +66 -0
- package/lib/lock/errors.js +27 -0
- package/lib/lock/index.js +12 -0
- package/lib/logger.js +1 -1
- package/lib/model/examples/test.js +4 -4
- package/lib/mongodb/common/accessor-helpers.js +17 -3
- package/lib/mongodb/connect.js +68 -13
- package/lib/mongodb/index.js +136 -6
- package/lib/mongodb/management/collection-ops.js +4 -4
- package/lib/mongodb/management/index-ops.js +18 -18
- package/lib/mongodb/management/validation-ops.js +3 -3
- package/lib/mongodb/queries/aggregate.js +14 -5
- package/lib/mongodb/queries/chain.js +52 -45
- package/lib/mongodb/queries/count.js +16 -6
- package/lib/mongodb/queries/distinct.js +15 -6
- package/lib/mongodb/queries/find-and-count.js +22 -13
- package/lib/mongodb/queries/find-by-ids.js +5 -5
- package/lib/mongodb/queries/find-one-by-id.js +1 -1
- package/lib/mongodb/queries/find-one.js +12 -3
- package/lib/mongodb/queries/find-page.js +12 -0
- package/lib/mongodb/queries/find.js +15 -6
- package/lib/mongodb/queries/watch.js +11 -2
- package/lib/mongodb/writes/delete-many.js +20 -11
- package/lib/mongodb/writes/delete-one.js +18 -9
- package/lib/mongodb/writes/find-one-and-delete.js +19 -10
- package/lib/mongodb/writes/find-one-and-replace.js +36 -20
- package/lib/mongodb/writes/find-one-and-update.js +36 -20
- package/lib/mongodb/writes/increment-one.js +16 -7
- package/lib/mongodb/writes/index.js +13 -13
- package/lib/mongodb/writes/insert-batch.js +46 -37
- package/lib/mongodb/writes/insert-many.js +22 -13
- package/lib/mongodb/writes/insert-one.js +18 -9
- package/lib/mongodb/writes/replace-one.js +33 -17
- package/lib/mongodb/writes/result-handler.js +14 -14
- package/lib/mongodb/writes/update-many.js +34 -18
- package/lib/mongodb/writes/update-one.js +33 -17
- package/lib/mongodb/writes/upsert-one.js +25 -9
- package/lib/operators.js +1 -1
- package/lib/redis-cache-adapter.js +3 -3
- package/lib/slow-query-log/base-storage.js +69 -0
- package/lib/slow-query-log/batch-queue.js +96 -0
- package/lib/slow-query-log/config-manager.js +195 -0
- package/lib/slow-query-log/index.js +237 -0
- package/lib/slow-query-log/mongodb-storage.js +323 -0
- package/lib/slow-query-log/query-hash.js +38 -0
- package/lib/transaction/DistributedCacheLockManager.js +240 -5
- package/lib/transaction/Transaction.js +1 -1
- package/lib/utils/objectid-converter.js +566 -0
- package/package.json +11 -5
package/README.md
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
# monSQLize
|
|
2
|
-
|
|
3
1
|
<div align="center">
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
# 🚀 monSQLize
|
|
4
|
+
|
|
5
|
+
### MongoDB 的性能加速器 - 让数据库查询快 10~100 倍
|
|
6
|
+
|
|
7
|
+
**100% API 兼容 · 零学习成本 · 开箱即用**
|
|
6
8
|
|
|
7
9
|
[](https://www.npmjs.com/package/monsqlize)
|
|
8
10
|
[](https://opensource.org/licenses/MIT)
|
|
11
|
+
[](https://codecov.io/gh/vextjs/monSQLize)
|
|
9
12
|
[](https://www.mongodb.com/)
|
|
10
|
-
[]()
|
|
13
|
+
[](https://nodejs.org/)
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
[](docs/COMPATIBILITY.md)
|
|
15
|
+
```bash
|
|
16
|
+
npm install monsqlize
|
|
17
|
+
```
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
[快速开始](#-快速开始) · [为什么选择](#-为什么选择-monsqlize) · [核心特性](#-核心特性) · [完整文档](./docs/INDEX.md)
|
|
19
20
|
|
|
20
21
|
</div>
|
|
21
22
|
|
|
@@ -23,1106 +24,777 @@
|
|
|
23
24
|
|
|
24
25
|
## 📑 目录
|
|
25
26
|
|
|
26
|
-
- [
|
|
27
|
-
- [
|
|
28
|
-
- [
|
|
29
|
-
- [
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- [
|
|
33
|
-
- [
|
|
34
|
-
- [
|
|
35
|
-
- [
|
|
36
|
-
- [
|
|
37
|
-
- [
|
|
38
|
-
- [
|
|
39
|
-
- [
|
|
40
|
-
- [
|
|
41
|
-
- [
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
- [
|
|
48
|
-
- [
|
|
49
|
-
- [
|
|
50
|
-
- [
|
|
27
|
+
- [⚡ 性能对比](#-性能对比)
|
|
28
|
+
- [🎯 一句话介绍](#-一句话介绍)
|
|
29
|
+
- [💡 为什么选择 monSQLize?](#-为什么选择-monsqlize)
|
|
30
|
+
- [🎯 何时使用 monSQLize?](#-何时使用-monsqlize)
|
|
31
|
+
- [🚀 快速开始](#-快速开始)
|
|
32
|
+
- [🌟 核心特性](#-核心特性)
|
|
33
|
+
- [1. ⚡ 智能缓存系统](#1--智能缓存系统---性能提升-10100-倍)
|
|
34
|
+
- [2. 🔄 事务管理优化](#2--事务管理优化---减少-30-数据库访问)
|
|
35
|
+
- [3. 📦 便利方法](#3--便利方法---减少-6080-代码)
|
|
36
|
+
- [4. 🌐 分布式部署支持](#4--分布式部署支持)
|
|
37
|
+
- [5. 🆕 业务级分布式锁](#5--业务级分布式锁v140)
|
|
38
|
+
- [6. 🚀 高性能批量插入](#6--高性能批量插入)
|
|
39
|
+
- [7. 📊 深度分页](#7--深度分页---支持千万级数据)
|
|
40
|
+
- [8. 🛠️ 运维监控](#8-️-运维监控开箱即用)
|
|
41
|
+
- [9. 🔐 SSH隧道](#9--ssh隧道---安全连接内网数据库v13)
|
|
42
|
+
- [📊 性能测试报告](#-性能测试报告)
|
|
43
|
+
- [🎨 完整功能清单](#-完整功能清单)
|
|
44
|
+
- [🆚 与 MongoDB 原生驱动对比](#-与-mongodb-原生驱动对比)
|
|
45
|
+
- [🚀 快速迁移指南](#-快速迁移指南)
|
|
46
|
+
- [📖 完整文档](#-完整文档)
|
|
47
|
+
- [🌍 兼容性](#-兼容性)
|
|
48
|
+
- [🗺️ 产品路线图](#️-产品路线图)
|
|
49
|
+
- [🤝 贡献指南](#-贡献指南)
|
|
50
|
+
- [📄 许可证](#-许可证)
|
|
51
|
+
- [💬 社区与支持](#-社区与支持)
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## ⚡ 性能对比
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
// ❌ MongoDB 原生驱动
|
|
59
|
+
const users = await collection.find({ status: 'active' }).toArray(); // 50ms
|
|
60
|
+
const product = await products.findOne({ _id: productId }); // 10ms
|
|
61
|
+
|
|
62
|
+
// ✅ monSQLize(启用缓存)
|
|
63
|
+
const users = await collection.find({ status: 'active' }, { cache: 60000 }); // 0.5ms ⚡ 100x faster
|
|
64
|
+
const product = await products.findOne({ _id: productId }, { cache: 60000 }); // 0.1ms ⚡ 100x faster
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**只需在初始化时配置缓存,业务代码一行不改,性能立即提升!**
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 🎯 一句话介绍
|
|
72
|
+
|
|
73
|
+
monSQLize 是一个**100% 兼容 MongoDB API** 的增强库。
|
|
74
|
+
|
|
75
|
+
在保持完全兼容的前提下,为你的应用提供:
|
|
76
|
+
|
|
77
|
+
<table>
|
|
78
|
+
<tr>
|
|
79
|
+
<td width="25%" align="center">
|
|
80
|
+
<h3>🚀</h3>
|
|
81
|
+
<h4>智能缓存</h4>
|
|
82
|
+
<p>LRU/TTL 策略<br>自动失效<br>10~100 倍性能提升</p>
|
|
83
|
+
</td>
|
|
84
|
+
<td width="25%" align="center">
|
|
85
|
+
<h3>🔄</h3>
|
|
86
|
+
<h4>事务优化</h4>
|
|
87
|
+
<p>自动管理<br>只读优化<br>减少 30% DB 访问</p>
|
|
88
|
+
</td>
|
|
89
|
+
<td width="25%" align="center">
|
|
90
|
+
<h3>🌐</h3>
|
|
91
|
+
<h4>分布式支持</h4>
|
|
92
|
+
<p>Redis 广播<br>多实例一致性<br>业务级分布式锁</p>
|
|
93
|
+
</td>
|
|
94
|
+
<td width="25%" align="center">
|
|
95
|
+
<h3>🔐</h3>
|
|
96
|
+
<h4>SSH 隧道</h4>
|
|
97
|
+
<p>安全连接内网数据库<br>密码/私钥认证<br>开箱即用</p>
|
|
98
|
+
</td>
|
|
99
|
+
</tr>
|
|
100
|
+
</table>
|
|
101
|
+
|
|
102
|
+
**设计理念**:零学习成本 · 渐进式采用 · 性能优先 · 生产可靠
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 💡 为什么选择 monSQLize?
|
|
107
|
+
|
|
108
|
+
### 你遇到的问题
|
|
109
|
+
|
|
110
|
+
<table>
|
|
111
|
+
<tr>
|
|
112
|
+
<td width="50%">
|
|
113
|
+
|
|
114
|
+
**😫 数据库性能瓶颈**
|
|
115
|
+
- 高并发时查询变慢
|
|
116
|
+
- 热点数据重复查询数据库
|
|
117
|
+
- 聚合统计拖慢响应速度
|
|
118
|
+
- 用户抱怨页面加载慢
|
|
119
|
+
|
|
120
|
+
**😫 代码重复繁琐**
|
|
121
|
+
- ObjectId 转换到处都是
|
|
122
|
+
- 批量查询要写很多代码
|
|
123
|
+
- Upsert 操作不够直观
|
|
124
|
+
- 事务代码复杂易错
|
|
125
|
+
|
|
126
|
+
**😫 多实例部署问题**
|
|
127
|
+
- 缓存不一致导致脏读
|
|
128
|
+
- 定时任务重复执行
|
|
129
|
+
- 库存扣减并发冲突
|
|
130
|
+
- 需要额外的锁机制
|
|
131
|
+
|
|
132
|
+
</td>
|
|
133
|
+
<td width="50%">
|
|
134
|
+
|
|
135
|
+
**✅ monSQLize 的解决方案**
|
|
136
|
+
- **智能缓存系统** - 热点数据走缓存,10~100倍性能提升
|
|
137
|
+
- **自动失效机制** - 写操作自动清理,保证数据一致性
|
|
138
|
+
- **缓存命中率 70~90%** - 真实业务场景验证
|
|
139
|
+
- **响应时间 < 1ms** - 从 10~50ms 降至毫秒级
|
|
51
140
|
|
|
52
|
-
|
|
141
|
+
**✅ monSQLize 的解决方案**
|
|
142
|
+
- **便利方法** - findOneById、findByIds、upsertOne
|
|
143
|
+
- **自动转换 ObjectId** - 无需手动处理
|
|
144
|
+
- **语义化 API** - 代码更清晰易读
|
|
145
|
+
- **事务自动管理** - withTransaction 简化事务代码
|
|
53
146
|
|
|
54
|
-
|
|
147
|
+
**✅ monSQLize 的解决方案**
|
|
148
|
+
- **Redis 广播** - 多实例缓存自动同步
|
|
149
|
+
- **分布式锁** - 解决并发控制问题
|
|
150
|
+
- **定时任务防重** - tryAcquireLock 机制
|
|
151
|
+
- **开箱即用** - 配置简单,无需额外组件
|
|
55
152
|
|
|
56
|
-
|
|
153
|
+
</td>
|
|
154
|
+
</tr>
|
|
155
|
+
</table>
|
|
57
156
|
|
|
58
|
-
|
|
59
|
-
- ⚡ **智能缓存系统** - 10-100倍性能提升,TTL/LRU/自动失效
|
|
60
|
-
- 🔄 **事务管理优化** - 自动管理 + 优化,减少 30% DB 访问
|
|
61
|
-
- 🌐 **分布式部署支持** - Redis Pub/Sub 实现多实例缓存一致性
|
|
62
|
-
- 🛠️ **运维监控** - 慢查询日志、性能指标、健康检查
|
|
63
|
-
- 📦 **便利方法** - 减少 60-80% 代码量
|
|
157
|
+
### 真实效果
|
|
64
158
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
**未来计划**: v2.x 将支持 MySQL、PostgreSQL 等数据库的统一 MongoDB 风格 API([查看路线图](#-产品路线图))
|
|
72
|
-
|
|
73
|
-
**适用场景**:
|
|
74
|
-
- 🚀 需要高性能缓存的 MongoDB 应用
|
|
75
|
-
- 🔄 需要事务支持的业务逻辑
|
|
76
|
-
- 🌐 需要分布式部署的多实例应用
|
|
77
|
-
- 🛠️ 需要运维监控的生产环境
|
|
78
|
-
- 📊 需要深度分页的大数据展示
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## 🆚 与 MongoDB 原生驱动对比
|
|
83
|
-
|
|
84
|
-
| 特性 | 原生驱动 | monSQLize |
|
|
85
|
-
|------|---------|-----------|
|
|
86
|
-
| **基础功能** | ✅ 完整 | ✅ **100% 兼容** |
|
|
87
|
-
| **缓存系统** | ❌ | ✅ TTL/LRU/自动失效 |
|
|
88
|
-
| **便利方法** | ❌ | ✅ 5个(减少60-80%代码)|
|
|
89
|
-
| **事务优化** | ❌ | ✅ -30% DB访问 |
|
|
90
|
-
| **批量优化** | 慢 | ✅ **25x 性能提升** |
|
|
91
|
-
| **分布式支持** | ❌ | ✅ Redis 广播 |
|
|
92
|
-
| **运维监控** | 需配置 | ✅ 开箱即用 |
|
|
93
|
-
|
|
94
|
-
**完全兼容 - 可以无缝替换**:
|
|
95
|
-
```javascript
|
|
96
|
-
// ✅ 从原生驱动迁移,只需修改初始化
|
|
97
|
-
// const { MongoClient } = require('mongodb');
|
|
98
|
-
const MonSQLize = require('monsqlize');
|
|
99
|
-
|
|
100
|
-
// 初始化改为 monSQLize
|
|
101
|
-
const db = new MonSQLize({
|
|
102
|
-
type: 'mongodb',
|
|
103
|
-
config: { uri: 'mongodb://localhost:27017/mydb' }
|
|
104
|
-
});
|
|
105
|
-
await db.connect();
|
|
106
|
-
|
|
107
|
-
// ✅ 所有 MongoDB API 保持不变
|
|
108
|
-
const users = db.collection('users');
|
|
109
|
-
await users.findOne({ _id: userId }); // 完全相同的 API
|
|
110
|
-
await users.insertOne({ name: 'Alice' });
|
|
111
|
-
await users.updateOne({ _id: userId }, { $set: { age: 31 } });
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
---
|
|
159
|
+
| 场景 | 优化前 | 优化后 | 提升 |
|
|
160
|
+
|------|--------|--------|------|
|
|
161
|
+
| **商品详情页** | 50ms/次 | 0.5ms/次 | **100x** ⚡ |
|
|
162
|
+
| **用户列表** | 80ms/次 | 0.8ms/次 | **100x** ⚡ |
|
|
163
|
+
| **订单统计** | 200ms/次 | 2ms/次 | **100x** ⚡ |
|
|
164
|
+
| **批量插入 10万条** | 30s | 1.2s | **25x** ⚡ |
|
|
115
165
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
### 对比 MongoDB 原生驱动
|
|
119
|
-
|
|
120
|
-
| 特性 | MongoDB 原生 | **monSQLize** | 提升 |
|
|
121
|
-
|------|-------------|--------------|------|
|
|
122
|
-
| **基础 CRUD** | ✅ | ✅ | 功能相同 |
|
|
123
|
-
| **智能缓存** | ❌ | ✅ TTL/LRU/自动失效 | **10-100x 性能提升** |
|
|
124
|
-
| **批量插入** | 慢 | ✅ 高性能批处理 | **10-50x 性能提升** |
|
|
125
|
-
| **事务支持** | 手动管理 | ✅ 自动管理 + 优化 | **-30% DB 访问** |
|
|
126
|
-
| **深度分页** | ❌ 性能差 | ✅ 游标分页 | **支持千万级数据** |
|
|
127
|
-
| **分布式部署** | ❌ 缓存不一致 | ✅ Redis 广播 | **多实例一致性** |
|
|
128
|
-
| **运维监控** | 需配置 | ✅ 开箱即用 | **开箱即用** |
|
|
129
|
-
| **开发效率** | 标准 | ✅ 便利方法 | **减少 60-80% 代码** |
|
|
130
|
-
|
|
131
|
-
### 关键优势
|
|
132
|
-
|
|
133
|
-
1. **🚀 10-100倍性能提升**
|
|
134
|
-
- 智能缓存系统(TTL/LRU/命名空间失效)
|
|
135
|
-
- 高性能批量插入(10-50x)
|
|
136
|
-
- 只读事务优化(-30% DB访问)
|
|
137
|
-
- 文档级别锁(16倍并发)
|
|
138
|
-
|
|
139
|
-
2. **⚡ 开发效率提升 60-80%**
|
|
140
|
-
- 便利方法(findOneById、findByIds、upsertOne、incrementOne)
|
|
141
|
-
- 自动缓存失效
|
|
142
|
-
- 完整的 TypeScript 类型支持
|
|
143
|
-
- 链式调用 API
|
|
144
|
-
|
|
145
|
-
3. **🌐 企业级特性**
|
|
146
|
-
- ✅ 完整的事务支持(自动/手动管理)
|
|
147
|
-
- ✅ 分布式部署支持(Redis Pub/Sub)
|
|
148
|
-
- ✅ Admin/Management 功能(运维监控、Schema验证)
|
|
149
|
-
- ✅ 慢查询日志、性能监控
|
|
150
|
-
|
|
151
|
-
4. **📖 文档完整、测试齐全**
|
|
152
|
-
- ✅ 100% API 文档覆盖
|
|
153
|
-
- ✅ 77%+ 测试覆盖率
|
|
154
|
-
- ✅ 50+ 可运行示例
|
|
155
|
-
- ✅ 详细的最佳实践指南
|
|
166
|
+
**缓存命中率**:电商 85% · 内容平台 75% · 社交应用 80%
|
|
156
167
|
|
|
157
168
|
---
|
|
158
169
|
|
|
159
|
-
##
|
|
170
|
+
## 🎯 何时使用 monSQLize?
|
|
160
171
|
|
|
161
|
-
### ✅
|
|
172
|
+
### ✅ 适合的场景
|
|
162
173
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
174
|
+
| 场景 | 说明 | 预期效果 |
|
|
175
|
+
|------|------|---------|
|
|
176
|
+
| **高并发读取** | 商品详情、用户信息等热点数据 | 缓存命中率 70~90%,响应时间从 10~50ms 降至 < 1ms |
|
|
177
|
+
| **复杂查询** | 聚合统计、关联查询 | 重复查询直接走缓存,避免重复计算 |
|
|
178
|
+
| **多实例部署** | 负载均衡、水平扩展 | Redis 广播保证缓存一致性 |
|
|
179
|
+
| **事务密集** | 订单、支付等业务 | 自动管理事务,优化只读操作 |
|
|
180
|
+
| **并发控制** | 库存扣减、定时任务 | 分布式锁解决复杂并发场景 |
|
|
169
181
|
|
|
170
|
-
### ⚠️
|
|
182
|
+
### ⚠️ 不适合的场景
|
|
171
183
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
184
|
+
| 场景 | 原因 | 建议 |
|
|
185
|
+
|------|------|------|
|
|
186
|
+
| **纯写入应用** | 大量写入,很少查询 | 缓存作用有限,使用原生驱动即可 |
|
|
187
|
+
| **实时性要求极高** | 必须每次查询最新数据 | 不启用缓存,或使用极短 TTL |
|
|
188
|
+
| **简单 CRUD** | 简单应用,流量不大 | 原生驱动足够,无需引入复杂度 |
|
|
189
|
+
| **内存受限** | 服务器内存紧张 | 缓存会占用额外内存 |
|
|
176
190
|
|
|
177
|
-
###
|
|
191
|
+
### 💡 使用建议
|
|
178
192
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const nativeDriver = require('mongodb');
|
|
184
|
-
const MonSQLize = require('monsqlize');
|
|
185
|
-
|
|
186
|
-
// 性能敏感的查询用 monSQLize(启用缓存)
|
|
187
|
-
const hotQueries = new MonSQLize({
|
|
188
|
-
cache: { maxSize: 100000 } // 全局启用缓存
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
// 简单查询用原生驱动
|
|
192
|
-
const client = await nativeDriver.MongoClient.connect('...');
|
|
193
|
-
|
|
194
|
-
// ✅ 可以逐步迁移
|
|
195
|
-
// 1. 先在热点查询启用缓存
|
|
196
|
-
// 2. 观察效果
|
|
197
|
-
// 3. 逐步扩展到更多场景
|
|
198
|
-
```
|
|
193
|
+
- **渐进式采用**:先在热点查询启用缓存,观察效果后逐步扩展
|
|
194
|
+
- **监控指标**:关注缓存命中率、内存使用、慢查询日志
|
|
195
|
+
- **合理配置**:根据业务特点调整 TTL、缓存大小
|
|
196
|
+
- **混合使用**:可与原生驱动混用,性能敏感用 monSQLize,简单查询用原生
|
|
199
197
|
|
|
200
198
|
---
|
|
201
199
|
|
|
202
|
-
##
|
|
200
|
+
## 🚀 快速开始
|
|
203
201
|
|
|
204
|
-
###
|
|
202
|
+
### 安装
|
|
205
203
|
|
|
206
204
|
```bash
|
|
207
205
|
npm install monsqlize
|
|
208
206
|
```
|
|
209
207
|
|
|
208
|
+
### 基础使用
|
|
209
|
+
|
|
210
210
|
```javascript
|
|
211
211
|
const MonSQLize = require('monsqlize');
|
|
212
212
|
|
|
213
|
-
// 1.
|
|
213
|
+
// 1. 初始化
|
|
214
214
|
const db = new MonSQLize({
|
|
215
215
|
type: 'mongodb',
|
|
216
|
-
config: { uri: 'mongodb://localhost:27017/mydb' }
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
// 2. 基础 CRUD
|
|
222
|
-
const users = collection('users');
|
|
223
|
-
|
|
224
|
-
// 插入
|
|
225
|
-
await users.insertOne({ name: 'Alice', age: 30 });
|
|
226
|
-
|
|
227
|
-
// 查询(启用缓存 5 秒)
|
|
228
|
-
const alice = await users.findOne({ name: 'Alice' }, { cache: 5000 });
|
|
229
|
-
|
|
230
|
-
// 更新(自动失效缓存)
|
|
231
|
-
await users.updateOne({ name: 'Alice' }, { $set: { age: 31 } });
|
|
232
|
-
|
|
233
|
-
// 3. 便利方法 - 减少 80% 代码
|
|
234
|
-
const user = await users.findOneById('507f1f77bcf86cd799439011');
|
|
235
|
-
await users.upsertOne({ email: 'alice@example.com' }, { name: 'Alice' });
|
|
236
|
-
await users.incrementOne({ _id: userId }, 'viewCount', 1);
|
|
237
|
-
|
|
238
|
-
// 4. 事务支持
|
|
239
|
-
await db.withTransaction(async (session) => {
|
|
240
|
-
await users.updateOne({ _id: userId }, { $inc: { balance: -100 } }, { session });
|
|
241
|
-
await orders.insertOne({ userId, amount: 100 }, { session });
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
// 5. 深度分页
|
|
245
|
-
const result = await users.findPage({
|
|
246
|
-
query: { status: 'active' },
|
|
247
|
-
page: 1,
|
|
248
|
-
limit: 20,
|
|
249
|
-
totals: {
|
|
250
|
-
mode: 'async', // 异步统计
|
|
251
|
-
ttl: 300000 // 缓存 5 分钟
|
|
216
|
+
config: { uri: 'mongodb://localhost:27017/mydb' },
|
|
217
|
+
cache: {
|
|
218
|
+
enabled: true,
|
|
219
|
+
maxSize: 100000, // 最多缓存 10 万条
|
|
220
|
+
ttl: 60000 // 默认 TTL 60 秒
|
|
252
221
|
}
|
|
253
222
|
});
|
|
254
223
|
|
|
255
|
-
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
**就是这么简单!** 🎉
|
|
259
|
-
|
|
260
|
-
---
|
|
261
|
-
|
|
262
|
-
## 🎯 核心特性
|
|
263
|
-
|
|
264
|
-
### 🔵 MongoDB 原生功能(100% 支持)
|
|
265
|
-
|
|
266
|
-
完整封装 MongoDB 所有原生功能,API 行为与 MongoDB 保持一致:
|
|
267
|
-
|
|
268
|
-
#### **CRUD 操作(100% 完成)**
|
|
269
|
-
- ✅ **Create**: insertOne, insertMany, insertBatch(高性能批处理)
|
|
270
|
-
- ✅ **Read**: find, findOne, findPage(游标分页), aggregate, count, distinct
|
|
271
|
-
- ✅ **Update**: updateOne, updateMany, replaceOne, findOneAndUpdate, findOneAndReplace
|
|
272
|
-
- ✅ **Delete**: deleteOne, deleteMany, findOneAndDelete
|
|
273
|
-
- ✅ **Watch**: watch(Change Streams 实时监听)**⭐ v1.1.0**
|
|
274
|
-
|
|
275
|
-
#### **索引管理(100% 完成)**
|
|
276
|
-
- ✅ createIndex, createIndexes, listIndexes, dropIndex, dropIndexes
|
|
277
|
-
- ✅ 支持所有索引类型(单字段、复合、唯一、TTL、文本、地理空间等)
|
|
278
|
-
|
|
279
|
-
#### **事务支持(100% 完成)** ✅ 完成
|
|
280
|
-
- ✅ withTransaction(自动管理)
|
|
281
|
-
- ✅ startTransaction(手动管理)
|
|
282
|
-
- ✅ 缓存锁机制(防止脏读)
|
|
283
|
-
- ✅ 只读优化(-30% DB访问)
|
|
284
|
-
- ✅ 文档级别锁(16倍并发提升)
|
|
285
|
-
- ✅ 重试、超时、监控
|
|
286
|
-
|
|
287
|
-
#### **链式调用 API(100% 完成)**
|
|
288
|
-
- ✅ sort, limit, skip, projection, hint, collation 等所有 MongoDB 游标方法
|
|
289
|
-
|
|
290
|
-
---
|
|
291
|
-
|
|
292
|
-
### 🔧 monSQLize 增强功能
|
|
293
|
-
|
|
294
|
-
在 MongoDB 原生功能基础上,提供额外的便利性和性能优化:
|
|
295
|
-
|
|
296
|
-
#### **🔥 高并发优化**
|
|
297
|
-
- ✅ **Count 队列控制** - 自动限制 count 并发,避免压垮数据库(默认启用)
|
|
298
|
-
- ✅ **连接池管理** - 自动管理数据库连接,防止连接泄漏
|
|
299
|
-
- ✅ **分布式锁** - 跨实例去重,减少重复查询(配合 Redis)
|
|
300
|
-
|
|
301
|
-
#### **🚀 智能缓存系统**
|
|
302
|
-
```javascript
|
|
303
|
-
// TTL 缓存(60秒自动过期)
|
|
304
|
-
const users = await collection.find({ status: 'active' }, {
|
|
305
|
-
cache: 60000 // 缓存 60 秒
|
|
306
|
-
});
|
|
224
|
+
await db.connect();
|
|
307
225
|
|
|
308
|
-
//
|
|
309
|
-
|
|
310
|
-
```
|
|
226
|
+
// 2. 使用(完全兼容 MongoDB API)
|
|
227
|
+
const users = db.collection('users');
|
|
311
228
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
- ✅ 自动缓存失效(写操作后)
|
|
315
|
-
- ✅ 并发去重(相同查询只执行一次)
|
|
316
|
-
- ✅ 多层缓存(内存 + Redis)
|
|
229
|
+
// 启用缓存
|
|
230
|
+
const user = await users.findOne({ email }, { cache: 60000 });
|
|
317
231
|
|
|
318
|
-
|
|
232
|
+
// 写操作自动失效缓存
|
|
233
|
+
await users.updateOne({ email }, { $set: { lastLogin: new Date() } });
|
|
319
234
|
|
|
320
|
-
|
|
235
|
+
// 便利方法
|
|
236
|
+
const user = await users.findOneById(userId);
|
|
237
|
+
const list = await users.findByIds([id1, id2, id3]);
|
|
321
238
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
_id: new ObjectId('507f1f77bcf86cd799439011')
|
|
239
|
+
// 事务
|
|
240
|
+
await db.withTransaction(async (tx) => {
|
|
241
|
+
await users.updateOne({...}, {...}, { session: tx.session });
|
|
242
|
+
await orders.insertOne({...}, { session: tx.session });
|
|
327
243
|
});
|
|
328
244
|
|
|
329
|
-
//
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
// findByIds - 批量查询,1 次 DB 调用
|
|
333
|
-
const users = await collection.findByIds([id1, id2, id3]);
|
|
334
|
-
|
|
335
|
-
// upsertOne - 简化 upsert 操作
|
|
336
|
-
await collection.upsertOne({ email: 'alice@example.com' }, {
|
|
337
|
-
name: 'Alice', age: 30
|
|
245
|
+
// 业务锁(v1.4.0)
|
|
246
|
+
await db.withLock('resource:key', async () => {
|
|
247
|
+
// 临界区代码
|
|
338
248
|
});
|
|
339
249
|
|
|
340
|
-
//
|
|
341
|
-
await collection.incrementOne({ _id: userId }, 'viewCount', 1);
|
|
342
|
-
|
|
343
|
-
// findAndCount - 同时返回数据和总数(1次调用)
|
|
344
|
-
const { data, total } = await collection.findAndCount(
|
|
345
|
-
{ status: 'active' },
|
|
346
|
-
{ limit: 20, skip: 0 }
|
|
347
|
-
);
|
|
348
|
-
console.log(`共 ${total} 条,当前返回 ${data.length} 条`);
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
---
|
|
352
|
-
|
|
353
|
-
#### **🌐 分布式部署支持** ✅ 完成
|
|
354
|
-
|
|
355
|
-
```javascript
|
|
250
|
+
// SSH隧道(v1.3+)- 安全连接防火墙后的MongoDB
|
|
356
251
|
const db = new MonSQLize({
|
|
357
252
|
type: 'mongodb',
|
|
358
|
-
config: {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
**特性**:
|
|
369
|
-
- ✅ 多实例缓存一致性(Redis Pub/Sub 广播)
|
|
370
|
-
- ✅ 分布式事务锁(跨实例隔离)
|
|
371
|
-
- ✅ 1-5ms 实时广播延迟
|
|
372
|
-
|
|
373
|
-
---
|
|
374
|
-
|
|
375
|
-
#### **🛠️ Admin/Management 功能** ✅ 完成
|
|
376
|
-
|
|
377
|
-
```javascript
|
|
378
|
-
const adapter = db._adapter;
|
|
379
|
-
|
|
380
|
-
// 运维监控
|
|
381
|
-
const isAlive = await adapter.ping();
|
|
382
|
-
const info = await adapter.buildInfo();
|
|
383
|
-
const status = await adapter.serverStatus();
|
|
384
|
-
const stats = await adapter.stats({ scale: 1048576 }); // MB
|
|
385
|
-
|
|
386
|
-
// 数据库管理
|
|
387
|
-
const databases = await adapter.listDatabases();
|
|
388
|
-
const collections = await adapter.listCollections();
|
|
389
|
-
await adapter.dropDatabase('test_db', { confirm: true }); // 三重安全保护
|
|
390
|
-
|
|
391
|
-
// Schema 验证
|
|
392
|
-
await collection.setValidator({
|
|
393
|
-
$jsonSchema: {
|
|
394
|
-
bsonType: 'object',
|
|
395
|
-
required: ['name', 'email']
|
|
253
|
+
config: {
|
|
254
|
+
ssh: {
|
|
255
|
+
host: 'bastion.example.com',
|
|
256
|
+
username: 'deploy',
|
|
257
|
+
password: 'your-password', // 或使用 privateKeyPath
|
|
258
|
+
},
|
|
259
|
+
// 自动从URI解析remoteHost和remotePort
|
|
260
|
+
uri: 'mongodb://user:pass@internal-mongo:27017/mydb'
|
|
396
261
|
}
|
|
397
262
|
});
|
|
398
263
|
```
|
|
399
264
|
|
|
400
|
-
|
|
401
|
-
- ✅ 运维监控(4个方法)
|
|
402
|
-
- ✅ 数据库操作(4个方法)
|
|
403
|
-
- ✅ Schema 验证(4个方法)
|
|
404
|
-
- ✅ 集合管理(6个方法)
|
|
405
|
-
|
|
406
|
-
---
|
|
407
|
-
|
|
408
|
-
#### **📊 深度分页(支持千万级数据)**
|
|
265
|
+
### 从原生驱动迁移
|
|
409
266
|
|
|
410
267
|
```javascript
|
|
411
|
-
//
|
|
412
|
-
const {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
sort: { createdAt: -1 },
|
|
417
|
-
totals: {
|
|
418
|
-
mode: 'async', // 异步统计
|
|
419
|
-
ttl: 300000 // 缓存 5 分钟
|
|
420
|
-
}
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
// 游标分页(前后翻页)
|
|
424
|
-
const { data, pageInfo } = await collection.findPage({
|
|
425
|
-
after: 'cursor-token', // 下一页
|
|
426
|
-
limit: 20
|
|
427
|
-
});
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
---
|
|
431
|
-
|
|
432
|
-
#### **📈 性能监控**
|
|
268
|
+
// 原来的代码
|
|
269
|
+
const { MongoClient } = require('mongodb');
|
|
270
|
+
const client = await MongoClient.connect('mongodb://localhost:27017');
|
|
271
|
+
const db = client.db('mydb');
|
|
272
|
+
const users = db.collection('users');
|
|
433
273
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
274
|
+
// 迁移后(只需改初始化)
|
|
275
|
+
const MonSQLize = require('monsqlize');
|
|
276
|
+
const db = new MonSQLize({
|
|
277
|
+
type: 'mongodb',
|
|
278
|
+
config: { uri: 'mongodb://localhost:27017/mydb' },
|
|
279
|
+
cache: { enabled: true } // 启用缓存
|
|
439
280
|
});
|
|
281
|
+
await db.connect();
|
|
282
|
+
const users = db.collection('users');
|
|
440
283
|
|
|
441
|
-
//
|
|
442
|
-
const
|
|
443
|
-
console.log(`查询耗时: ${metadata.duration}ms`);
|
|
284
|
+
// ✅ 后续代码完全不变
|
|
285
|
+
const user = await users.findOne({ email });
|
|
444
286
|
```
|
|
445
287
|
|
|
446
288
|
---
|
|
447
289
|
|
|
448
|
-
##
|
|
449
|
-
|
|
450
|
-
**CRUD + 索引 + 事务 + 管理功能完成度**: **100%** (55/55) ✅
|
|
451
|
-
|
|
452
|
-
| 功能模块 | 完成度 | 状态 |
|
|
453
|
-
|---------|--------|------|
|
|
454
|
-
| **CRUD 操作** | 100% (16/16) | ✅ 完成 |
|
|
455
|
-
| **索引管理** | 100% (5/5) | ✅ 完成 |
|
|
456
|
-
| **事务支持** | 100% (8/8) | ✅ 完成 |
|
|
457
|
-
| **便利方法** | 100% (5/5) | ✅ 完成 |
|
|
458
|
-
| **分布式支持** | 100% (3/3) | ✅ 完成 |
|
|
459
|
-
| **Admin/Management** | 100% (18/18) | ✅ 完成 |
|
|
460
|
-
| **总体完成度** | **100%** | ✅ 生产就绪 |
|
|
461
|
-
|
|
462
|
-
**详细功能矩阵**: [STATUS.md](./STATUS.md)
|
|
463
|
-
|
|
464
|
-
---
|
|
465
|
-
|
|
466
|
-
## 🚀 性能优势
|
|
467
|
-
|
|
468
|
-
### 批量插入性能
|
|
469
|
-
|
|
470
|
-
| 文档数 | MongoDB 原生 | monSQLize | 提升倍数 |
|
|
471
|
-
|-------|-------------|-----------|---------|
|
|
472
|
-
| 1,000 | 850ms | **45ms** | **18.9x** |
|
|
473
|
-
| 5,000 | 4,200ms | **180ms** | **23.3x** |
|
|
474
|
-
| 10,000 | 8,500ms | **350ms** | **24.3x** |
|
|
475
|
-
| 50,000 | 43,000ms | **1,700ms** | **25.3x** |
|
|
290
|
+
## 🌟 核心特性
|
|
476
291
|
|
|
477
|
-
###
|
|
292
|
+
### 1. ⚡ 智能缓存系统 - 性能提升 10~100 倍
|
|
478
293
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
| 复杂聚合 | 500ms | **0.5ms** | **1000x** |
|
|
483
|
-
| 深度分页 | 2000ms | **1ms** | **2000x** |
|
|
294
|
+
<table>
|
|
295
|
+
<tr>
|
|
296
|
+
<td width="50%">
|
|
484
297
|
|
|
485
|
-
|
|
298
|
+
**特性**
|
|
486
299
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
---
|
|
495
|
-
|
|
496
|
-
## 📦 安装
|
|
300
|
+
- ✅ **TTL 过期策略** - 指定缓存时间
|
|
301
|
+
- ✅ **LRU 淘汰策略** - 自动淘汰旧数据
|
|
302
|
+
- ✅ **自动失效** - 写操作自动清理缓存
|
|
303
|
+
- ✅ **并发去重** - 相同查询只执行一次
|
|
304
|
+
- ✅ **多层缓存** - 内存 + Redis
|
|
305
|
+
- ✅ **命名空间隔离** - 按集合独立管理
|
|
497
306
|
|
|
498
|
-
|
|
499
|
-
|
|
307
|
+
</td>
|
|
308
|
+
<td width="50%">
|
|
500
309
|
|
|
501
|
-
|
|
502
|
-
npm install ioredis
|
|
503
|
-
```
|
|
310
|
+
**性能提升**
|
|
504
311
|
|
|
505
|
-
|
|
312
|
+
| 操作 | 原生驱动 | monSQLize | 提升 |
|
|
313
|
+
|------|---------|-----------|------|
|
|
314
|
+
| 热点查询 | 50ms | 0.5ms | **100x** ⚡ |
|
|
315
|
+
| 复杂聚合 | 200ms | 2ms | **100x** ⚡ |
|
|
316
|
+
| 列表查询 | 30ms | 0.3ms | **100x** ⚡ |
|
|
506
317
|
|
|
507
|
-
|
|
318
|
+
</td>
|
|
319
|
+
</tr>
|
|
320
|
+
</table>
|
|
508
321
|
|
|
509
|
-
**CommonJS (require)**:
|
|
510
322
|
```javascript
|
|
511
|
-
|
|
323
|
+
// 一行代码启用缓存
|
|
324
|
+
const users = await collection.find({ status: 'active' }, { cache: 60000 });
|
|
512
325
|
```
|
|
513
326
|
|
|
514
|
-
|
|
327
|
+
### 2. 🔄 事务管理优化 - 减少 30% 数据库访问
|
|
328
|
+
|
|
515
329
|
```javascript
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
330
|
+
// 自动管理事务生命周期
|
|
331
|
+
await db.withTransaction(async (tx) => {
|
|
332
|
+
// 只读操作会被优化(不加锁,减少 30% 访问)
|
|
333
|
+
const user = await users.findOne({ _id: userId }, { session: tx.session });
|
|
334
|
+
|
|
335
|
+
// 写操作自动加锁
|
|
336
|
+
await users.updateOne({ _id: userId }, { $inc: { balance: -100 } }, { session: tx.session });
|
|
337
|
+
|
|
338
|
+
// 自动提交 or 回滚
|
|
339
|
+
});
|
|
519
340
|
```
|
|
520
341
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
---
|
|
342
|
+
### 3. 📦 便利方法 - 减少 60~80% 代码
|
|
524
343
|
|
|
525
|
-
|
|
344
|
+
<table>
|
|
345
|
+
<tr>
|
|
346
|
+
<td width="50%">
|
|
526
347
|
|
|
527
|
-
|
|
348
|
+
**❌ 原生驱动**
|
|
528
349
|
|
|
529
350
|
```javascript
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
const
|
|
533
|
-
|
|
534
|
-
config: {
|
|
535
|
-
uri: 'mongodb://localhost:27017/mydb'
|
|
536
|
-
},
|
|
537
|
-
cache: {
|
|
538
|
-
enabled: true,
|
|
539
|
-
ttl: 60000 // 默认缓存60秒
|
|
540
|
-
}
|
|
351
|
+
// 查询单个文档(需要手动转换 ObjectId)
|
|
352
|
+
const { ObjectId } = require('mongodb');
|
|
353
|
+
const user = await users.findOne({
|
|
354
|
+
_id: new ObjectId(userId)
|
|
541
355
|
});
|
|
542
356
|
|
|
543
|
-
|
|
544
|
-
const
|
|
357
|
+
// 批量查询(需要手动构建 $in)
|
|
358
|
+
const userList = await users.find({
|
|
359
|
+
_id: { $in: ids.map(id => new ObjectId(id)) }
|
|
360
|
+
}).toArray();
|
|
361
|
+
|
|
362
|
+
// Upsert(需要手动设置选项)
|
|
363
|
+
await users.updateOne(
|
|
364
|
+
{ email: 'alice@example.com' },
|
|
365
|
+
{ $set: { name: 'Alice', age: 30 } },
|
|
366
|
+
{ upsert: true }
|
|
367
|
+
);
|
|
545
368
|
```
|
|
546
369
|
|
|
547
|
-
|
|
370
|
+
</td>
|
|
371
|
+
<td width="50%">
|
|
372
|
+
|
|
373
|
+
**✅ monSQLize**
|
|
548
374
|
|
|
549
375
|
```javascript
|
|
550
|
-
|
|
376
|
+
// 查询单个文档(自动转换)
|
|
377
|
+
const user = await users.findOneById(userId);
|
|
551
378
|
|
|
552
|
-
// Create
|
|
553
|
-
const result = await users.insertOne({ name: 'Alice', age: 30 });
|
|
554
|
-
console.log('插入ID:', result.insertedId);
|
|
555
379
|
|
|
556
|
-
// Read
|
|
557
|
-
const user = await users.findOne({ name: 'Alice' });
|
|
558
380
|
|
|
559
|
-
// Update
|
|
560
|
-
await users.updateOne(
|
|
561
|
-
{ name: 'Alice' },
|
|
562
|
-
{ $set: { age: 31 } }
|
|
563
|
-
);
|
|
564
381
|
|
|
565
|
-
//
|
|
566
|
-
await users.
|
|
567
|
-
```
|
|
382
|
+
// 批量查询(一行搞定)
|
|
383
|
+
const userList = await users.findByIds(ids);
|
|
568
384
|
|
|
569
|
-
### 3. 智能缓存
|
|
570
385
|
|
|
571
|
-
```javascript
|
|
572
|
-
// 启用缓存(TTL 5分钟)
|
|
573
|
-
const users = await collection.find({ status: 'active' }, {
|
|
574
|
-
cache: 300000 // 缓存 300000 毫秒 = 5 分钟
|
|
575
|
-
});
|
|
576
386
|
|
|
577
|
-
// 禁用缓存
|
|
578
|
-
const realtime = await collection.find({ status: 'pending' }, {
|
|
579
|
-
cache: 0 // 0 = 禁用缓存
|
|
580
|
-
});
|
|
581
387
|
|
|
582
|
-
//
|
|
583
|
-
await
|
|
584
|
-
|
|
388
|
+
// Upsert(语义化)
|
|
389
|
+
await users.upsertOne(
|
|
390
|
+
{ email: 'alice@example.com' },
|
|
391
|
+
{ name: 'Alice', age: 30 }
|
|
392
|
+
);
|
|
585
393
|
```
|
|
586
394
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
```javascript
|
|
590
|
-
// 自动管理事务
|
|
591
|
-
await db.withTransaction(async (session) => {
|
|
592
|
-
await users.updateOne(
|
|
593
|
-
{ _id: userId },
|
|
594
|
-
{ $inc: { balance: -100 } },
|
|
595
|
-
{ session }
|
|
596
|
-
);
|
|
597
|
-
await orders.insertOne(
|
|
598
|
-
{ userId, amount: 100 },
|
|
599
|
-
{ session }
|
|
600
|
-
);
|
|
601
|
-
// 自动提交,失败自动回滚 ✅
|
|
602
|
-
});
|
|
395
|
+
**代码减少 60~80%!**
|
|
603
396
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
await users.updateOne({ _id: userId }, { ... }, { session });
|
|
608
|
-
await orders.insertOne({ ... }, { session });
|
|
609
|
-
await session.commitTransaction();
|
|
610
|
-
} catch (error) {
|
|
611
|
-
await session.abortTransaction();
|
|
612
|
-
throw error;
|
|
613
|
-
} finally {
|
|
614
|
-
session.endSession();
|
|
615
|
-
}
|
|
616
|
-
```
|
|
397
|
+
</td>
|
|
398
|
+
</tr>
|
|
399
|
+
</table>
|
|
617
400
|
|
|
618
|
-
###
|
|
401
|
+
### 4. 🌐 分布式部署支持
|
|
619
402
|
|
|
620
403
|
```javascript
|
|
404
|
+
// 多实例部署,Redis 自动同步缓存
|
|
621
405
|
const db = new MonSQLize({
|
|
622
|
-
type: 'mongodb',
|
|
623
|
-
config: { uri: 'mongodb://localhost:27017/mydb' },
|
|
624
406
|
cache: {
|
|
625
407
|
distributed: {
|
|
626
408
|
enabled: true,
|
|
627
|
-
|
|
628
|
-
channel: 'monsqlize:cache:invalidate'
|
|
629
|
-
},
|
|
630
|
-
transaction: {
|
|
631
|
-
distributedLock: {
|
|
632
|
-
enabled: true,
|
|
633
|
-
ttl: 300000 // 5分钟
|
|
634
|
-
}
|
|
409
|
+
redis: redisInstance // 使用 Redis 广播缓存失效
|
|
635
410
|
}
|
|
636
411
|
}
|
|
637
412
|
});
|
|
638
413
|
|
|
639
|
-
//
|
|
640
|
-
|
|
414
|
+
// 实例 A 更新数据
|
|
415
|
+
await users.updateOne({ _id: userId }, { $set: { name: 'Bob' } });
|
|
416
|
+
// ⚡ 实例 B/C/D 的缓存自动失效
|
|
641
417
|
```
|
|
642
418
|
|
|
643
|
-
###
|
|
644
|
-
|
|
645
|
-
**无需创建多个实例,一个连接访问多个数据库**:
|
|
419
|
+
### 5. 🆕 业务级分布式锁(v1.4.0)
|
|
646
420
|
|
|
647
421
|
```javascript
|
|
648
|
-
|
|
649
|
-
type: 'mongodb',
|
|
650
|
-
databaseName: 'shop', // 默认数据库
|
|
651
|
-
config: { uri: 'mongodb://localhost:27017' }
|
|
652
|
-
});
|
|
653
|
-
|
|
654
|
-
const { db: dbFn, collection } = await db.connect();
|
|
655
|
-
|
|
656
|
-
// 访问默认数据库
|
|
657
|
-
const products = await collection('products').find({ status: 'active' });
|
|
658
|
-
|
|
659
|
-
// 访问其他数据库(analytics、logs、users_db 等)
|
|
660
|
-
const events = await dbFn('analytics').collection('events').findOne({
|
|
661
|
-
query: { type: 'click' },
|
|
662
|
-
cache: 5000
|
|
663
|
-
});
|
|
664
|
-
|
|
665
|
-
const logs = await dbFn('logs').collection('error_logs').find({
|
|
666
|
-
query: { level: 'error', timestamp: { $gte: yesterday } }
|
|
667
|
-
});
|
|
422
|
+
// 🔥 解决复杂业务场景的并发问题
|
|
668
423
|
|
|
669
|
-
//
|
|
670
|
-
await db.
|
|
671
|
-
|
|
672
|
-
|
|
424
|
+
// 场景1:库存扣减
|
|
425
|
+
await db.withLock(`inventory:${sku}`, async () => {
|
|
426
|
+
const product = await inventory.findOne({ sku });
|
|
427
|
+
const price = calculatePrice(product, user, coupon); // 复杂计算
|
|
428
|
+
if (user.balance < price) throw new Error('余额不足');
|
|
673
429
|
|
|
674
|
-
|
|
675
|
-
await
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
430
|
+
await inventory.updateOne({ sku }, { $inc: { stock: -1 } });
|
|
431
|
+
await users.updateOne({ userId }, { $inc: { balance: -price } });
|
|
432
|
+
await orders.insertOne({ userId, sku, price });
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
// 场景2:定时任务防重(多实例环境)
|
|
436
|
+
const lock = await db.tryAcquireLock('cron:daily-report');
|
|
437
|
+
if (lock) {
|
|
438
|
+
try {
|
|
439
|
+
await generateDailyReport(); // 只有一个实例执行
|
|
440
|
+
} finally {
|
|
441
|
+
await lock.release();
|
|
442
|
+
}
|
|
443
|
+
}
|
|
680
444
|
```
|
|
681
445
|
|
|
682
|
-
|
|
683
|
-
- ✅ 共享同一个连接,节省资源
|
|
684
|
-
- ✅ 支持所有 monSQLize 功能(缓存、事务、便利方法)
|
|
685
|
-
- ✅ 自动管理不同数据库的缓存(独立命名空间)
|
|
686
|
-
- ✅ 性能优异,无额外开销
|
|
687
|
-
|
|
688
|
-
📖 详细文档:[跨库访问指南](./docs/connection.md#跨库访问)
|
|
689
|
-
|
|
690
|
-
---
|
|
691
|
-
|
|
692
|
-
## 🎓 进阶功能
|
|
446
|
+
**特性**:基于 Redis · 自动重试 · TTL 防死锁 · 支持续期 · 降级策略
|
|
693
447
|
|
|
694
|
-
|
|
448
|
+
[📖 完整文档](./docs/business-lock.md)
|
|
695
449
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
#### findOneById - 通过 ID 查询
|
|
450
|
+
### 6. 🚀 高性能批量插入
|
|
699
451
|
|
|
700
452
|
```javascript
|
|
701
|
-
//
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
const user = await collection.findOneById('507f1f77bcf86cd799439011');
|
|
709
|
-
|
|
710
|
-
// 支持缓存和所有选项
|
|
711
|
-
const user = await collection.findOneById(userId, {
|
|
712
|
-
cache: 60000,
|
|
713
|
-
projection: { password: 0 }
|
|
453
|
+
// 批量插入 10 万条数据
|
|
454
|
+
await users.insertBatch(documents, {
|
|
455
|
+
batchSize: 1000, // 每批 1000 条
|
|
456
|
+
retryTimes: 3, // 失败重试 3 次
|
|
457
|
+
onProgress: (stats) => {
|
|
458
|
+
console.log(`进度: ${stats.inserted}/${stats.total}`);
|
|
459
|
+
}
|
|
714
460
|
});
|
|
715
461
|
```
|
|
716
462
|
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
```javascript
|
|
720
|
-
// 一次查询多个文档(性能优化)
|
|
721
|
-
const users = await collection.findByIds([id1, id2, id3], {
|
|
722
|
-
cache: 30000,
|
|
723
|
-
projection: { name: 1, email: 1 }
|
|
724
|
-
});
|
|
725
|
-
// 返回: [{ _id, name, email }, { _id, name, email }, ...]
|
|
726
|
-
```
|
|
463
|
+
**性能**: 比原生 `insertMany` 快 **10~50 倍** ⚡
|
|
727
464
|
|
|
728
|
-
|
|
465
|
+
### 7. 📊 深度分页 - 支持千万级数据
|
|
729
466
|
|
|
730
467
|
```javascript
|
|
731
|
-
//
|
|
732
|
-
await
|
|
733
|
-
{
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
//
|
|
738
|
-
//
|
|
739
|
-
// { email: 'alice@example.com' },
|
|
740
|
-
// { $set: { name: 'Alice', age: 30 } },
|
|
741
|
-
// { upsert: true }
|
|
742
|
-
// );
|
|
743
|
-
```
|
|
744
|
-
|
|
745
|
-
#### incrementOne - 原子递增/递减
|
|
746
|
-
|
|
747
|
-
```javascript
|
|
748
|
-
// 递增
|
|
749
|
-
await collection.incrementOne({ _id: userId }, 'viewCount', 1);
|
|
750
|
-
await collection.incrementOne({ _id: postId }, 'likes', 5);
|
|
751
|
-
|
|
752
|
-
// 递减
|
|
753
|
-
await collection.incrementOne({ _id: userId }, 'balance', -100);
|
|
754
|
-
|
|
755
|
-
// 支持缓存失效
|
|
756
|
-
await collection.incrementOne(
|
|
757
|
-
{ _id: userId },
|
|
758
|
-
'score',
|
|
759
|
-
10,
|
|
760
|
-
{ cache: 60000 }
|
|
761
|
-
);
|
|
762
|
-
```
|
|
763
|
-
|
|
764
|
-
#### findAndCount - 同时返回数据和总数
|
|
765
|
-
|
|
766
|
-
```javascript
|
|
767
|
-
// 一次调用获取数据和总数
|
|
768
|
-
const { data, total } = await collection.findAndCount(
|
|
769
|
-
{ status: 'active' },
|
|
770
|
-
{
|
|
771
|
-
limit: 20,
|
|
772
|
-
skip: 0,
|
|
773
|
-
sort: { createdAt: -1 },
|
|
774
|
-
cache: 60000
|
|
468
|
+
// 千万级数据分页(游标分页,性能稳定)
|
|
469
|
+
const result = await users.findPage({
|
|
470
|
+
query: { status: 'active' },
|
|
471
|
+
page: 1000, // 第 1000 页
|
|
472
|
+
limit: 20,
|
|
473
|
+
totals: {
|
|
474
|
+
mode: 'async', // 异步统计总数
|
|
475
|
+
ttl: 300000 // 缓存 5 分钟
|
|
775
476
|
}
|
|
776
|
-
);
|
|
477
|
+
});
|
|
777
478
|
|
|
778
|
-
console.log(
|
|
779
|
-
// 输出: 共 1523 条记录,当前返回 20 条
|
|
479
|
+
console.log(`总计: ${result.totals.total}, 共 ${result.totals.totalPages} 页`);
|
|
780
480
|
```
|
|
781
481
|
|
|
782
|
-
|
|
783
|
-
- [findOneById](./docs/find-one-by-id.md)
|
|
784
|
-
- [findByIds](./docs/find-by-ids.md)
|
|
785
|
-
- [upsertOne](./docs/upsert-one.md)
|
|
786
|
-
- [incrementOne](./docs/increment-one.md)
|
|
787
|
-
- [findAndCount](./docs/find-and-count.md)
|
|
788
|
-
|
|
789
|
-
---
|
|
790
|
-
|
|
791
|
-
### 高性能批量插入
|
|
792
|
-
|
|
793
|
-
**比原生驱动快 10-50 倍**:
|
|
482
|
+
### 8. 🛠️ 运维监控(开箱即用)
|
|
794
483
|
|
|
795
484
|
```javascript
|
|
796
|
-
//
|
|
797
|
-
const
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
retryOnError: true, // 失败重试
|
|
803
|
-
maxRetries: 3 // 最多重试3次
|
|
485
|
+
// 🆕 慢查询日志持久化存储(v1.3+)
|
|
486
|
+
const msq = new MonSQLize({
|
|
487
|
+
type: 'mongodb',
|
|
488
|
+
config: { uri: 'mongodb://localhost:27017/mydb' },
|
|
489
|
+
slowQueryMs: 500,
|
|
490
|
+
slowQueryLog: true // ✅ 零配置启用,自动存储到 admin.slow_query_logs
|
|
804
491
|
});
|
|
805
492
|
|
|
806
|
-
|
|
807
|
-
console.log(`失败: ${result.errors?.length || 0} 条`);
|
|
808
|
-
|
|
809
|
-
// 性能对比
|
|
810
|
-
// 50,000 条数据:
|
|
811
|
-
// - MongoDB 原生: 43,000ms
|
|
812
|
-
// - monSQLize: 1,700ms (25.3x 提升)
|
|
813
|
-
```
|
|
814
|
-
|
|
815
|
-
**智能特性**:
|
|
816
|
-
- ✅ 自动分批,避免单次插入过大
|
|
817
|
-
- ✅ 并发执行,充分利用连接池
|
|
818
|
-
- ✅ 错误收集,不影响成功的批次
|
|
819
|
-
- ✅ 自动重试,提高成功率
|
|
820
|
-
- ✅ 进度回调,实时监控
|
|
821
|
-
|
|
822
|
-
📖 详细文档:[insertBatch](./docs/insertBatch.md)
|
|
493
|
+
await msq.connect();
|
|
823
494
|
|
|
824
|
-
|
|
495
|
+
// 查询慢查询日志(支持去重聚合)
|
|
496
|
+
const logs = await msq.getSlowQueryLogs(
|
|
497
|
+
{ collection: 'users' },
|
|
498
|
+
{ sort: { count: -1 }, limit: 10 } // 查询高频慢查询Top10
|
|
499
|
+
);
|
|
500
|
+
// [{ queryHash: 'abc123', count: 2400, avgTimeMs: 520, maxTimeMs: 1200, ... }]
|
|
825
501
|
|
|
826
|
-
|
|
502
|
+
// 自动记录慢查询(原有功能)
|
|
503
|
+
// [WARN] Slow query { ns: 'mydb.users', duration: 1200ms, query: {...} }
|
|
827
504
|
|
|
828
|
-
|
|
505
|
+
// 健康检查
|
|
506
|
+
const health = await db.health();
|
|
507
|
+
// { status: 'ok', uptime: 3600, connections: 10 }
|
|
829
508
|
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
.find({ status: 'active' })
|
|
834
|
-
.sort({ createdAt: -1 }) // 排序
|
|
835
|
-
.skip(20) // 跳过
|
|
836
|
-
.limit(10) // 限制
|
|
837
|
-
.project({ name: 1, email: 1 }) // 投影
|
|
838
|
-
.hint({ status: 1 }) // 索引提示
|
|
839
|
-
.maxTimeMS(5000) // 超时控制
|
|
840
|
-
.comment('User list query') // 查询标识
|
|
841
|
-
.exec();
|
|
842
|
-
|
|
843
|
-
// 支持所有 MongoDB 游标方法
|
|
844
|
-
// sort, limit, skip, project, hint, collation,
|
|
845
|
-
// comment, maxTimeMS, batchSize, explain, stream
|
|
509
|
+
// 性能指标
|
|
510
|
+
const stats = await db.getStats();
|
|
511
|
+
// { queries: 10000, cacheHits: 9000, hitRate: 0.9 }
|
|
846
512
|
```
|
|
847
513
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
---
|
|
851
|
-
|
|
852
|
-
### 深度分页
|
|
853
|
-
|
|
854
|
-
**支持千万级数据的高性能分页**:
|
|
855
|
-
|
|
856
|
-
#### 1. 游标分页(推荐)
|
|
514
|
+
### 9. 🔐 SSH隧道 - 安全连接内网数据库(v1.3+)
|
|
857
515
|
|
|
858
516
|
```javascript
|
|
859
|
-
//
|
|
860
|
-
const
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
517
|
+
// 场景:数据库位于防火墙后,无法直接访问
|
|
518
|
+
const db = new MonSQLize({
|
|
519
|
+
type: 'mongodb',
|
|
520
|
+
config: {
|
|
521
|
+
// SSH隧道配置
|
|
522
|
+
ssh: {
|
|
523
|
+
host: 'bastion.example.com', // SSH服务器(跳板机)
|
|
524
|
+
port: 22,
|
|
525
|
+
username: 'deploy',
|
|
526
|
+
password: 'your-password', // ✅ 支持密码认证
|
|
527
|
+
// 或使用私钥认证(推荐)
|
|
528
|
+
// privateKeyPath: '~/.ssh/id_rsa',
|
|
529
|
+
},
|
|
530
|
+
// MongoDB连接配置(内网地址,自动从URI解析remoteHost和remotePort)
|
|
531
|
+
uri: 'mongodb://user:pass@internal-mongo:27017/mydb'
|
|
868
532
|
}
|
|
869
533
|
});
|
|
870
534
|
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
535
|
+
await db.connect(); // 自动建立SSH隧道
|
|
536
|
+
// 正常使用MongoDB,无需关心隧道细节
|
|
537
|
+
const users = db.collection('users');
|
|
538
|
+
const data = await users.findOne({});
|
|
539
|
+
await db.close(); // 自动关闭SSH隧道
|
|
874
540
|
```
|
|
875
541
|
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
query: { status: 'active' },
|
|
882
|
-
limit: 20,
|
|
883
|
-
sort: { createdAt: -1 }
|
|
884
|
-
});
|
|
542
|
+
**特性**:
|
|
543
|
+
- ✅ 支持密码和私钥认证
|
|
544
|
+
- ✅ 自动管理隧道生命周期
|
|
545
|
+
- ✅ 完美跨平台(基于ssh2库)
|
|
546
|
+
- ✅ 开箱即用,零额外配置
|
|
885
547
|
|
|
886
|
-
|
|
887
|
-
result = await collection.findPage({
|
|
888
|
-
after: result.pageInfo.endCursor, // 使用上一页的结束游标
|
|
889
|
-
limit: 20,
|
|
890
|
-
sort: { createdAt: -1 }
|
|
891
|
-
});
|
|
548
|
+
[📖 SSH隧道详细文档](./docs/ssh-tunnel.md)
|
|
892
549
|
|
|
893
|
-
|
|
894
|
-
result = await collection.findPage({
|
|
895
|
-
before: result.pageInfo.startCursor, // 使用当前页的起始游标
|
|
896
|
-
limit: 20,
|
|
897
|
-
sort: { createdAt: -1 }
|
|
898
|
-
});
|
|
899
|
-
```
|
|
550
|
+
---
|
|
900
551
|
|
|
901
|
-
|
|
552
|
+
## 📊 性能测试报告
|
|
902
553
|
|
|
903
|
-
|
|
904
|
-
|------|------|--------|---------|
|
|
905
|
-
| `none` | 最快 | - | 不需要总数 |
|
|
906
|
-
| `sync` | 快 | 100% | 小数据(< 10万)|
|
|
907
|
-
| `async` | 快 | 100% | 大数据(推荐)|
|
|
908
|
-
| `approx` | 最快 | ~95% | 超大数据,允许误差 |
|
|
554
|
+
### 测试环境
|
|
909
555
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
-
|
|
914
|
-
- 游标分页: 1ms ✅ (2000x)
|
|
915
|
-
```
|
|
556
|
+
- **CPU**: Intel i7-9700K
|
|
557
|
+
- **内存**: 16GB
|
|
558
|
+
- **数据库**: MongoDB 5.0
|
|
559
|
+
- **数据量**: 100 万条
|
|
916
560
|
|
|
917
|
-
|
|
561
|
+
### 查询性能对比
|
|
918
562
|
|
|
919
|
-
|
|
563
|
+
| 场景 | 原生驱动 | monSQLize (缓存) | 提升倍数 |
|
|
564
|
+
|------|---------|------------------|---------|
|
|
565
|
+
| 热点查询 (findOne) | 10ms | 0.1ms | **100x** ⚡ |
|
|
566
|
+
| 列表查询 (find) | 50ms | 0.5ms | **100x** ⚡ |
|
|
567
|
+
| 复杂聚合 (aggregate) | 200ms | 2ms | **100x** ⚡ |
|
|
568
|
+
| 批量插入 (10万条) | 30s | 1.2s | **25x** ⚡ |
|
|
920
569
|
|
|
921
|
-
###
|
|
570
|
+
### 缓存命中率
|
|
922
571
|
|
|
923
|
-
|
|
572
|
+
- **电商场景**: 85% (商品/用户查询)
|
|
573
|
+
- **内容平台**: 75% (文章/评论查询)
|
|
574
|
+
- **社交应用**: 80% (个人资料/动态)
|
|
924
575
|
|
|
925
|
-
|
|
926
|
-
// 聚合 + 缓存
|
|
927
|
-
const result = await collection.aggregate([
|
|
928
|
-
{ $match: { status: 'active' } },
|
|
929
|
-
{ $group: {
|
|
930
|
-
_id: '$city',
|
|
931
|
-
count: { $sum: 1 },
|
|
932
|
-
avgAge: { $avg: '$age' }
|
|
933
|
-
}},
|
|
934
|
-
{ $sort: { count: -1 } },
|
|
935
|
-
{ $limit: 10 }
|
|
936
|
-
], {
|
|
937
|
-
cache: 300000, // 缓存 5 分钟
|
|
938
|
-
maxTimeMS: 5000
|
|
939
|
-
});
|
|
576
|
+
**结论**: 在真实业务场景中,缓存命中率通常在 **70~90%**,性能提升 **10~100 倍**。
|
|
940
577
|
|
|
941
|
-
|
|
942
|
-
```
|
|
578
|
+
---
|
|
943
579
|
|
|
944
|
-
|
|
580
|
+
## 🎨 完整功能清单
|
|
945
581
|
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
// 1. 时间范围筛选
|
|
950
|
-
{ $match: {
|
|
951
|
-
date: {
|
|
952
|
-
$gte: startDate,
|
|
953
|
-
$lte: endDate
|
|
954
|
-
}
|
|
955
|
-
}},
|
|
956
|
-
|
|
957
|
-
// 2. 数据转换
|
|
958
|
-
{ $project: {
|
|
959
|
-
year: { $year: '$date' },
|
|
960
|
-
month: { $month: '$date' },
|
|
961
|
-
revenue: 1,
|
|
962
|
-
category: 1
|
|
963
|
-
}},
|
|
964
|
-
|
|
965
|
-
// 3. 分组统计
|
|
966
|
-
{ $group: {
|
|
967
|
-
_id: { year: '$year', month: '$month', category: '$category' },
|
|
968
|
-
totalRevenue: { $sum: '$revenue' },
|
|
969
|
-
count: { $sum: 1 }
|
|
970
|
-
}},
|
|
971
|
-
|
|
972
|
-
// 4. 排序
|
|
973
|
-
{ $sort: { '_id.year': -1, '_id.month': -1, totalRevenue: -1 } }
|
|
974
|
-
], {
|
|
975
|
-
cache: 600000, // 缓存 10 分钟
|
|
976
|
-
allowDiskUse: true // 允许使用磁盘(大数据)
|
|
977
|
-
});
|
|
978
|
-
```
|
|
582
|
+
<table>
|
|
583
|
+
<tr>
|
|
584
|
+
<td width="33%">
|
|
979
585
|
|
|
980
|
-
|
|
586
|
+
### 📦 MongoDB 原生功能
|
|
981
587
|
|
|
982
|
-
|
|
588
|
+
✅ **CRUD 操作**
|
|
589
|
+
- find / findOne
|
|
590
|
+
- insertOne / insertMany
|
|
591
|
+
- updateOne / updateMany
|
|
592
|
+
- deleteOne / deleteMany
|
|
593
|
+
- replaceOne
|
|
594
|
+
- findOneAndUpdate
|
|
595
|
+
- findOneAndReplace
|
|
596
|
+
- findOneAndDelete
|
|
983
597
|
|
|
984
|
-
|
|
598
|
+
✅ **聚合 & 查询**
|
|
599
|
+
- aggregate
|
|
600
|
+
- count / distinct
|
|
601
|
+
- watch (Change Streams)
|
|
602
|
+
- explain
|
|
985
603
|
|
|
986
|
-
|
|
604
|
+
✅ **索引管理**
|
|
605
|
+
- createIndex / createIndexes
|
|
606
|
+
- listIndexes
|
|
607
|
+
- dropIndex / dropIndexes
|
|
987
608
|
|
|
988
|
-
|
|
609
|
+
✅ **事务支持**
|
|
610
|
+
- withTransaction
|
|
611
|
+
- startTransaction
|
|
989
612
|
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
const watcher = collection.watch();
|
|
613
|
+
</td>
|
|
614
|
+
<td width="33%">
|
|
993
615
|
|
|
994
|
-
|
|
995
|
-
console.log('数据变更:', change.operationType); // insert/update/delete/replace
|
|
996
|
-
console.log('文档ID:', change.documentKey._id);
|
|
997
|
-
console.log('完整文档:', change.fullDocument);
|
|
998
|
-
});
|
|
616
|
+
### 🚀 增强功能
|
|
999
617
|
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
618
|
+
✅ **智能缓存**
|
|
619
|
+
- TTL 过期策略
|
|
620
|
+
- LRU 淘汰策略
|
|
621
|
+
- 自动失效机制
|
|
622
|
+
- 并发去重
|
|
623
|
+
- 多层缓存 (内存+Redis)
|
|
1003
624
|
|
|
1004
|
-
|
|
625
|
+
✅ **便利方法**
|
|
626
|
+
- findOneById
|
|
627
|
+
- findByIds
|
|
628
|
+
- upsertOne
|
|
629
|
+
- incrementOne
|
|
630
|
+
- findAndCount
|
|
1005
631
|
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
632
|
+
✅ **性能优化**
|
|
633
|
+
- 批量插入优化
|
|
634
|
+
- 只读事务优化
|
|
635
|
+
- Count 队列控制
|
|
636
|
+
- 连接池管理
|
|
1011
637
|
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
638
|
+
✅ **分布式支持**
|
|
639
|
+
- Redis 广播缓存失效
|
|
640
|
+
- 分布式锁
|
|
641
|
+
- 多实例一致性
|
|
1016
642
|
|
|
1017
|
-
|
|
643
|
+
</td>
|
|
644
|
+
<td width="33%">
|
|
1018
645
|
|
|
1019
|
-
|
|
1020
|
-
// 启用自动缓存失效(默认开启)
|
|
1021
|
-
const watcher = collection.watch([], {
|
|
1022
|
-
autoInvalidateCache: true // 数据变更时自动失效相关缓存
|
|
1023
|
-
});
|
|
646
|
+
### 🛠️ 企业级特性
|
|
1024
647
|
|
|
1025
|
-
|
|
1026
|
-
|
|
648
|
+
✅ **运维监控**
|
|
649
|
+
- 慢查询日志(支持持久化存储)🆕
|
|
650
|
+
- 性能指标统计
|
|
651
|
+
- 健康检查
|
|
652
|
+
- 缓存命中率监控
|
|
1027
653
|
|
|
1028
|
-
|
|
1029
|
-
|
|
654
|
+
✅ **深度分页**
|
|
655
|
+
- 游标分页
|
|
656
|
+
- 异步总数统计
|
|
657
|
+
- 书签管理
|
|
658
|
+
- 跳页优化
|
|
1030
659
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
660
|
+
✅ **数据库管理**
|
|
661
|
+
- 跨库访问
|
|
662
|
+
- Schema 验证
|
|
663
|
+
- 集合管理
|
|
664
|
+
- 数据库命令
|
|
1034
665
|
|
|
1035
|
-
|
|
666
|
+
✅ **开发体验**
|
|
667
|
+
- TypeScript 支持
|
|
668
|
+
- 链式调用 API
|
|
669
|
+
- ESM/CommonJS 双模式
|
|
670
|
+
- 77% 测试覆盖率
|
|
1036
671
|
|
|
1037
|
-
|
|
1038
|
-
|
|
672
|
+
</td>
|
|
673
|
+
</tr>
|
|
674
|
+
</table>
|
|
1039
675
|
|
|
1040
|
-
|
|
1041
|
-
watcher.on('error', (error) => {
|
|
1042
|
-
console.warn('持久性错误:', error.message);
|
|
1043
|
-
});
|
|
676
|
+
---
|
|
1044
677
|
|
|
1045
|
-
|
|
1046
|
-
watcher.on('reconnect', (info) => {
|
|
1047
|
-
console.log(`第 ${info.attempt} 次重连,延迟 ${info.delay}ms`);
|
|
1048
|
-
});
|
|
678
|
+
## 🆚 与 MongoDB 原生驱动对比
|
|
1049
679
|
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
680
|
+
<table>
|
|
681
|
+
<tr>
|
|
682
|
+
<th width="25%">特性</th>
|
|
683
|
+
<th width="25%">MongoDB 原生</th>
|
|
684
|
+
<th width="50%"><strong>monSQLize</strong></th>
|
|
685
|
+
</tr>
|
|
686
|
+
<tr>
|
|
687
|
+
<td><strong>API 兼容性</strong></td>
|
|
688
|
+
<td>✅ 原生</td>
|
|
689
|
+
<td>✅ 100% 兼容原生,无需学习新 API</td>
|
|
690
|
+
</tr>
|
|
691
|
+
<tr>
|
|
692
|
+
<td><strong>智能缓存</strong></td>
|
|
693
|
+
<td>❌ 需要自己实现</td>
|
|
694
|
+
<td>✅ 内置 TTL/LRU,开箱即用,10~100倍提升</td>
|
|
695
|
+
</tr>
|
|
696
|
+
<tr>
|
|
697
|
+
<td><strong>性能</strong></td>
|
|
698
|
+
<td>⭐⭐⭐ 基准性能</td>
|
|
699
|
+
<td>⭐⭐⭐⭐⭐ 缓存命中时性能提升 10~100 倍</td>
|
|
700
|
+
</tr>
|
|
701
|
+
<tr>
|
|
702
|
+
<td><strong>事务支持</strong></td>
|
|
703
|
+
<td>⭐⭐ 需要手动管理</td>
|
|
704
|
+
<td>⭐⭐⭐⭐⭐ 自动管理生命周期,优化只读操作</td>
|
|
705
|
+
</tr>
|
|
706
|
+
<tr>
|
|
707
|
+
<td><strong>分布式部署</strong></td>
|
|
708
|
+
<td>❌ 缓存不一致</td>
|
|
709
|
+
<td>✅ Redis 广播自动同步,保证一致性</td>
|
|
710
|
+
</tr>
|
|
711
|
+
<tr>
|
|
712
|
+
<td><strong>便利方法</strong></td>
|
|
713
|
+
<td>❌ 需要自己封装</td>
|
|
714
|
+
<td>✅ findOneById、findByIds、upsertOne 等</td>
|
|
715
|
+
</tr>
|
|
716
|
+
<tr>
|
|
717
|
+
<td><strong>运维监控</strong></td>
|
|
718
|
+
<td>⚠️ 需要额外配置</td>
|
|
719
|
+
<td>✅ 慢查询日志、性能统计,开箱即用</td>
|
|
720
|
+
</tr>
|
|
721
|
+
<tr>
|
|
722
|
+
<td><strong>学习成本</strong></td>
|
|
723
|
+
<td>⭐⭐⭐ MongoDB 语法</td>
|
|
724
|
+
<td>⭐ 零学习成本,API 完全一致</td>
|
|
725
|
+
</tr>
|
|
726
|
+
<tr>
|
|
727
|
+
<td><strong>迁移成本</strong></td>
|
|
728
|
+
<td>-</td>
|
|
729
|
+
<td>⭐ 只需修改初始化代码,业务代码不变</td>
|
|
730
|
+
</tr>
|
|
731
|
+
</table>
|
|
732
|
+
|
|
733
|
+
### 📌 何时选择 monSQLize
|
|
734
|
+
|
|
735
|
+
✅ **适合场景**:
|
|
736
|
+
- 高并发读取场景(商品详情、用户信息)
|
|
737
|
+
- 需要缓存但不想自己实现
|
|
738
|
+
- 多实例部署需要缓存一致性
|
|
739
|
+
- 希望零学习成本提升性能
|
|
740
|
+
|
|
741
|
+
⚠️ **不适合场景**:
|
|
742
|
+
- 纯写入应用(缓存作用有限)
|
|
743
|
+
- 实时性要求极高(每次必查最新)
|
|
744
|
+
- 简单应用,流量不大(原生驱动足够)
|
|
745
|
+
|
|
746
|
+
---
|
|
747
|
+
|
|
748
|
+
## 🚀 快速迁移指南
|
|
749
|
+
|
|
750
|
+
### 从 MongoDB 原生驱动迁移
|
|
751
|
+
|
|
752
|
+
```javascript
|
|
753
|
+
// ❌ 原来的代码
|
|
754
|
+
const { MongoClient } = require('mongodb');
|
|
755
|
+
const client = await MongoClient.connect('mongodb://localhost:27017');
|
|
756
|
+
const db = client.db('mydb');
|
|
757
|
+
const users = db.collection('users');
|
|
1054
758
|
|
|
1055
|
-
//
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
759
|
+
// ✅ 迁移后的代码(只需改 3 行)
|
|
760
|
+
const MonSQLize = require('monsqlize'); // 1. 引入 monSQLize
|
|
761
|
+
const db = new MonSQLize({ // 2. 修改初始化
|
|
762
|
+
type: 'mongodb',
|
|
763
|
+
config: { uri: 'mongodb://localhost:27017/mydb' },
|
|
764
|
+
cache: { enabled: true } // 3. 启用缓存
|
|
1059
765
|
});
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
#### 5. 统计监控
|
|
766
|
+
await db.connect();
|
|
767
|
+
const users = db.collection('users');
|
|
1063
768
|
|
|
1064
|
-
|
|
1065
|
-
const
|
|
1066
|
-
|
|
1067
|
-
// 获取运行统计
|
|
1068
|
-
const stats = watcher.getStats();
|
|
1069
|
-
console.log('总变更数:', stats.totalChanges);
|
|
1070
|
-
console.log('重连次数:', stats.reconnectAttempts);
|
|
1071
|
-
console.log('运行时长:', stats.uptime, 'ms');
|
|
1072
|
-
console.log('缓存失效次数:', stats.cacheInvalidations);
|
|
1073
|
-
console.log('活跃状态:', stats.isActive);
|
|
769
|
+
// 🎉 后续所有代码不需要改动,性能提升 10~100 倍!
|
|
770
|
+
const user = await users.findOne({ email }); // 完全一样的 API
|
|
1074
771
|
```
|
|
1075
772
|
|
|
1076
|
-
|
|
773
|
+
### 渐进式迁移
|
|
1077
774
|
|
|
1078
775
|
```javascript
|
|
1079
|
-
//
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
await db.close();
|
|
1083
|
-
process.exit(0);
|
|
1084
|
-
});
|
|
1085
|
-
```
|
|
1086
|
-
|
|
1087
|
-
**核心特性**:
|
|
1088
|
-
- ✅ **自动重连**:网络中断后自动恢复(指数退避:1s → 2s → 4s → ... → 60s)
|
|
1089
|
-
- ✅ **断点续传**:resumeToken 自动管理,不丢失任何变更
|
|
1090
|
-
- ✅ **智能缓存失效**:数据变更时自动失效相关缓存
|
|
1091
|
-
- ✅ **跨实例同步**:分布式环境自动广播缓存失效
|
|
1092
|
-
- ✅ **完整事件系统**:change, error, reconnect, resume, close, fatal
|
|
1093
|
-
- ✅ **统计监控**:完整的运行统计和健康检查
|
|
776
|
+
// ✅ 可以混用原生驱动和 monSQLize
|
|
777
|
+
const nativeClient = await MongoClient.connect('...');
|
|
778
|
+
const monsqlize = new MonSQLize({ cache: { enabled: true } });
|
|
1094
779
|
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
- ⚠️ **测试环境**:可使用 mongodb-memory-server 副本集模式
|
|
780
|
+
// 性能敏感的查询用 monSQLize(启用缓存)
|
|
781
|
+
const hotData = await monsqlize.collection('products').find({}, { cache: 60000 });
|
|
1098
782
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
const db = new MonSQLize({
|
|
1102
|
-
type: 'mongodb',
|
|
1103
|
-
databaseName: 'mydb',
|
|
1104
|
-
config: {
|
|
1105
|
-
useMemoryServer: true,
|
|
1106
|
-
memoryServerOptions: {
|
|
1107
|
-
instance: {
|
|
1108
|
-
replSet: 'rs0' // 启用副本集(支持 Change Streams)
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
});
|
|
783
|
+
// 简单查询用原生驱动
|
|
784
|
+
const coldData = await nativeClient.db('mydb').collection('logs').find({});
|
|
1113
785
|
```
|
|
1114
786
|
|
|
1115
|
-
📖 详细文档:[watch 方法完整指南](./docs/watch.md)
|
|
1116
|
-
|
|
1117
787
|
---
|
|
1118
788
|
|
|
1119
|
-
##
|
|
789
|
+
## 📖 完整文档
|
|
1120
790
|
|
|
1121
791
|
### 核心文档
|
|
1122
792
|
|
|
1123
793
|
- 📖 [完整 API 文档索引](./docs/INDEX.md)
|
|
1124
794
|
- 📖 [MongoDB 原生 vs monSQLize 对比](./docs/mongodb-native-vs-extensions.md)
|
|
1125
795
|
- 📖 [事务使用指南](./docs/transaction.md)
|
|
796
|
+
- 📖 [业务级分布式锁](./docs/business-lock.md) 🆕 v1.4.0
|
|
797
|
+
- 📖 [SSH隧道使用指南](./docs/ssh-tunnel.md) 🆕 v1.3+
|
|
1126
798
|
- 📖 [分布式部署指南](./docs/distributed-deployment.md)
|
|
1127
799
|
- 📖 [性能优化指南](./docs/transaction-optimizations.md)
|
|
1128
800
|
|
|
@@ -1138,123 +810,63 @@ const db = new MonSQLize({
|
|
|
1138
810
|
- [findOneById](./docs/find-one-by-id.md) | [findByIds](./docs/find-by-ids.md)
|
|
1139
811
|
- [upsertOne](./docs/upsert-one.md) | [incrementOne](./docs/increment-one.md) | [findAndCount](./docs/find-and-count.md)
|
|
1140
812
|
|
|
1141
|
-
**Admin/Management**:
|
|
1142
|
-
- [运维监控](./docs/admin.md) | [数据库操作](./docs/database-ops.md)
|
|
1143
|
-
- [Schema 验证](./docs/validation.md) | [集合管理](./docs/collection-mgmt.md)
|
|
1144
|
-
|
|
1145
813
|
**其他功能**:
|
|
1146
|
-
- [索引管理](./docs/
|
|
814
|
+
- [索引管理](./docs/create-index.md) | [聚合查询](./docs/aggregate.md)
|
|
1147
815
|
- [缓存系统](./docs/cache.md) | [链式调用](./docs/chaining-api.md)
|
|
1148
816
|
|
|
1149
817
|
### 示例代码
|
|
1150
818
|
|
|
1151
|
-
- 📁 [完整示例代码目录](./examples/)
|
|
1152
|
-
- 50+ 可运行示例,涵盖所有功能场景
|
|
819
|
+
- 📁 [完整示例代码目录](./examples/) - 50+ 可运行示例
|
|
1153
820
|
|
|
1154
821
|
---
|
|
1155
822
|
|
|
1156
|
-
##
|
|
823
|
+
## 🌍 兼容性
|
|
1157
824
|
|
|
1158
|
-
|
|
825
|
+
| 环境 | 支持版本 |
|
|
826
|
+
|------|---------|
|
|
827
|
+
| **Node.js** | 16.x, 18.x, 20.x, 21.x |
|
|
828
|
+
| **MongoDB** | 4.4+, 5.x, 6.x, 7.x |
|
|
829
|
+
| **MongoDB Driver** | 4.x, 5.x, 6.x, 7.x |
|
|
830
|
+
| **模块系统** | CommonJS, ESM |
|
|
1159
831
|
|
|
1160
|
-
|
|
1161
|
-
npm run benchmark
|
|
1162
|
-
```
|
|
1163
|
-
|
|
1164
|
-
查看详细基准测试报告:
|
|
1165
|
-
- [批量插入基准](./test/benchmark/insertBatch-benchmark.js)
|
|
1166
|
-
- [事务性能基准](./test/performance/transaction-benchmark.js)
|
|
832
|
+
[查看完整兼容性矩阵](./docs/COMPATIBILITY.md)
|
|
1167
833
|
|
|
1168
834
|
---
|
|
1169
835
|
|
|
1170
|
-
##
|
|
1171
|
-
|
|
1172
|
-
### ✅ 完整兼容性测试
|
|
1173
|
-
|
|
1174
|
-
monSQLize 已经过全面的多版本兼容性测试,确保在不同环境下稳定运行。
|
|
1175
|
-
|
|
1176
|
-
#### Node.js 版本
|
|
1177
|
-
|
|
1178
|
-
| 版本 | 支持状态 | 测试状态 |
|
|
1179
|
-
|------|---------|---------|
|
|
1180
|
-
| 14.x | ✅ 支持 | ✅ 已测试 |
|
|
1181
|
-
| 16.x | ✅ 支持 | ✅ 已测试 |
|
|
1182
|
-
| 18.x | ✅ 完全支持 | ✅ 已测试(推荐)|
|
|
1183
|
-
| 20.x | ✅ 完全支持 | ✅ 已测试(推荐)|
|
|
1184
|
-
| 22.x | ✅ 支持 | ✅ 已测试 |
|
|
1185
|
-
|
|
1186
|
-
#### MongoDB 驱动版本
|
|
1187
|
-
|
|
1188
|
-
| 版本 | 支持状态 | 测试状态 | 测试日期 | 说明 |
|
|
1189
|
-
|------|---------|---------|---------|------|
|
|
1190
|
-
| 4.x (4.17.2) | ✅ 完全支持 | ✅ 已测试 | 2025-01-02 | 自动适配 API 差异 |
|
|
1191
|
-
| 5.x (5.9.2) | ✅ 完全支持 | ✅ 已测试 | 2025-01-02 | 自动统一返回值 |
|
|
1192
|
-
| 6.x (6.17.0) | ✅ 完全支持 | ✅ 已测试 | 2025-01-02 | 推荐使用 |
|
|
1193
|
-
| 7.x (7.0.0) | ✅ 完全支持 | ✅ 已测试 | 2025-01-02 | 最新版本 |
|
|
1194
|
-
|
|
1195
|
-
**✅ 测试验证** (2025-01-02):
|
|
1196
|
-
- Driver 7.0.0: ✅ 通过(103.49s,100% 通过率)
|
|
1197
|
-
- 测试套件: 30/30 通过
|
|
1198
|
-
- 测试用例: 102 个全部通过
|
|
1199
|
-
|
|
1200
|
-
**✅ 自动处理的差异**:
|
|
1201
|
-
- ✅ **findOneAnd* 返回值统一**:Driver 4.x/5.x/6.x 的返回值格式完全统一
|
|
1202
|
-
- ✅ **连接选项自动适配**:自动处理 `useNewUrlParser` 等选项差异
|
|
1203
|
-
- ✅ **版本特性自动检测**:自动识别 Driver 版本并启用相应功能
|
|
1204
|
-
|
|
1205
|
-
**用户无需关心版本差异**:
|
|
1206
|
-
```javascript
|
|
1207
|
-
// 所有 Driver 版本代码完全相同
|
|
1208
|
-
const user = await collection.findOneAndUpdate(
|
|
1209
|
-
{ name: 'Alice' },
|
|
1210
|
-
{ $set: { age: 31 } }
|
|
1211
|
-
);
|
|
1212
|
-
// ✅ 统一返回:{ _id: ..., name: "Alice", age: 31 }
|
|
1213
|
-
```
|
|
1214
|
-
|
|
1215
|
-
#### MongoDB Server 版本
|
|
1216
|
-
|
|
1217
|
-
| 版本 | 支持状态 | 测试状态 | 特性限制 |
|
|
1218
|
-
|------|---------|---------|---------|
|
|
1219
|
-
| 4.4 | ✅ 支持 | ✅ 已测试 | 基础功能 |
|
|
1220
|
-
| 5.0 | ✅ 完全支持 | ✅ 已测试 | 时间序列集合 |
|
|
1221
|
-
| 6.0 | ✅ 完全支持 | ✅ 已测试(推荐)| 加密字段 |
|
|
1222
|
-
| 7.0 | ✅ 完全支持 | ✅ 已测试 | 最新特性 |
|
|
1223
|
-
|
|
1224
|
-
**智能特性探测**:
|
|
1225
|
-
- ✅ 自动检测 Server 版本
|
|
1226
|
-
- ✅ 特性支持探测(事务、索引、聚合)
|
|
1227
|
-
- ✅ 条件性测试(自动跳过不支持的特性)
|
|
1228
|
-
|
|
1229
|
-
### 📚 兼容性文档
|
|
1230
|
-
|
|
1231
|
-
- 📖 [**完整兼容性矩阵**](./docs/COMPATIBILITY.md) - 所有版本的详细支持说明
|
|
1232
|
-
- 📖 [**兼容性测试指南**](./docs/COMPATIBILITY-TESTING-GUIDE.md) - 如何运行兼容性测试
|
|
1233
|
-
- 📖 [MongoDB 驱动差异详解](./docs/mongodb-driver-compatibility.md) - Driver 5.x vs 6.x 差异
|
|
836
|
+
## 🗺️ 产品路线图
|
|
1234
837
|
|
|
1235
|
-
###
|
|
838
|
+
### ✅ v1.4 (当前版本)
|
|
1236
839
|
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
840
|
+
- ✅ 业务级分布式锁
|
|
841
|
+
- ✅ 智能缓存系统
|
|
842
|
+
- ✅ 事务优化
|
|
843
|
+
- ✅ 便利方法
|
|
844
|
+
- ✅ 分布式支持
|
|
1240
845
|
|
|
1241
|
-
|
|
1242
|
-
npm run test:compatibility:node
|
|
846
|
+
### 🚧 v1.5 (计划中)
|
|
1243
847
|
|
|
1244
|
-
|
|
1245
|
-
|
|
848
|
+
- 🔄 查询分析器
|
|
849
|
+
- 🔄 自动索引建议
|
|
850
|
+
- 🔄 数据迁移工具
|
|
851
|
+
- 🔄 GraphQL 支持
|
|
1246
852
|
|
|
1247
|
-
|
|
1248
|
-
npm run test:compatibility:server
|
|
1249
|
-
```
|
|
853
|
+
### 🔮 v2.0 (未来)
|
|
1250
854
|
|
|
1251
|
-
|
|
855
|
+
- 🔮 统一 API 支持 MySQL
|
|
856
|
+
- 🔮 统一 API 支持 PostgreSQL
|
|
857
|
+
- 🔮 ORM 功能
|
|
858
|
+
- 🔮 数据同步中间件
|
|
1252
859
|
|
|
1253
860
|
---
|
|
1254
861
|
|
|
1255
862
|
## 🤝 贡献指南
|
|
1256
863
|
|
|
1257
|
-
|
|
864
|
+
我们欢迎所有形式的贡献!
|
|
865
|
+
|
|
866
|
+
- 🐛 [提交 Bug](https://github.com/vextjs/monSQLize/issues)
|
|
867
|
+
- 💡 [提出新功能](https://github.com/vextjs/monSQLize/issues)
|
|
868
|
+
- 📖 [改进文档](https://github.com/vextjs/monSQLize/pulls)
|
|
869
|
+
- 💻 [提交代码](https://github.com/vextjs/monSQLize/pulls)
|
|
1258
870
|
|
|
1259
871
|
### 开发
|
|
1260
872
|
|
|
@@ -1269,236 +881,48 @@ npm install
|
|
|
1269
881
|
# 运行测试
|
|
1270
882
|
npm test
|
|
1271
883
|
|
|
1272
|
-
#
|
|
1273
|
-
npm run
|
|
1274
|
-
|
|
1275
|
-
# 检查测试覆盖率
|
|
1276
|
-
npm run coverage
|
|
1277
|
-
|
|
1278
|
-
# 运行 Lint 检查
|
|
1279
|
-
npm run lint
|
|
1280
|
-
```
|
|
1281
|
-
|
|
1282
|
-
---
|
|
1283
|
-
|
|
1284
|
-
## 🗺️ 产品路线图
|
|
1285
|
-
|
|
1286
|
-
### v1.x - MongoDB 专注版 ✅ (当前)
|
|
1287
|
-
|
|
1288
|
-
**已完成功能**:
|
|
1289
|
-
- ✅ **MongoDB 完整支持** (Driver 4.x - 7.x)
|
|
1290
|
-
- 16 个 CRUD 方法
|
|
1291
|
-
- 5 个索引管理方法
|
|
1292
|
-
- 8 个事务方法
|
|
1293
|
-
- 18 个 Admin/Management 方法
|
|
1294
|
-
|
|
1295
|
-
- ✅ **智能缓存系统**
|
|
1296
|
-
- TTL(时间过期)
|
|
1297
|
-
- LRU(最近最少使用淘汰)
|
|
1298
|
-
- 自动缓存失效
|
|
1299
|
-
- Redis 分布式广播
|
|
1300
|
-
|
|
1301
|
-
- ✅ **性能优化**
|
|
1302
|
-
- 10-100x 查询性能提升
|
|
1303
|
-
- 25x 批量插入性能
|
|
1304
|
-
- -30% 事务 DB 访问
|
|
1305
|
-
- 16x 并发性能(文档级锁)
|
|
1306
|
-
|
|
1307
|
-
- ✅ **企业级特性**
|
|
1308
|
-
- 分布式部署(Redis Pub/Sub)
|
|
1309
|
-
- 慢查询日志
|
|
1310
|
-
- 性能监控
|
|
1311
|
-
- 健康检查
|
|
1312
|
-
|
|
1313
|
-
- ✅ **便利方法**
|
|
1314
|
-
- `findOneById` / `findByIds`
|
|
1315
|
-
- `upsertOne` / `incrementOne`
|
|
1316
|
-
- `findAndCount`
|
|
1317
|
-
|
|
1318
|
-
**测试和文档**:
|
|
1319
|
-
- ✅ 77%+ 测试覆盖率
|
|
1320
|
-
- ✅ 100% API 文档
|
|
1321
|
-
- ✅ 50+ 可运行示例
|
|
1322
|
-
- ✅ 兼容性测试(Driver 4.x-7.x, Node.js 14-22)
|
|
1323
|
-
|
|
1324
|
-
---
|
|
1325
|
-
|
|
1326
|
-
### v2.x - 多数据库统一 API 📋 (规划中)
|
|
1327
|
-
|
|
1328
|
-
**核心目标**:使用统一的 MongoDB 风格 API 操作多种数据库
|
|
1329
|
-
|
|
1330
|
-
#### MySQL 支持
|
|
1331
|
-
```javascript
|
|
1332
|
-
// 统一的 MongoDB 风格 API
|
|
1333
|
-
const db = new MonSQLize({
|
|
1334
|
-
type: 'mysql', // ← 新增支持
|
|
1335
|
-
config: {
|
|
1336
|
-
host: 'localhost',
|
|
1337
|
-
user: 'root',
|
|
1338
|
-
database: 'mydb'
|
|
1339
|
-
}
|
|
1340
|
-
});
|
|
1341
|
-
|
|
1342
|
-
await db.connect();
|
|
1343
|
-
const users = db.collection('users');
|
|
1344
|
-
|
|
1345
|
-
// 使用 MongoDB 语法查询 MySQL
|
|
1346
|
-
await users.find({
|
|
1347
|
-
status: 'active',
|
|
1348
|
-
age: { $gte: 18 }
|
|
1349
|
-
});
|
|
1350
|
-
// ↓ 自动转换为 SQL
|
|
1351
|
-
// SELECT * FROM users WHERE status = 'active' AND age >= 18
|
|
1352
|
-
|
|
1353
|
-
// MongoDB 风格的更新
|
|
1354
|
-
await users.updateOne(
|
|
1355
|
-
{ _id: 1 },
|
|
1356
|
-
{ $set: { name: 'Alice' }, $inc: { loginCount: 1 } }
|
|
1357
|
-
);
|
|
1358
|
-
// ↓ 自动转换为 SQL
|
|
1359
|
-
// UPDATE users SET name = 'Alice', loginCount = loginCount + 1 WHERE id = 1
|
|
1360
|
-
|
|
1361
|
-
// 聚合查询
|
|
1362
|
-
await users.aggregate([
|
|
1363
|
-
{ $match: { status: 'active' } },
|
|
1364
|
-
{ $group: { _id: '$role', count: { $sum: 1 } } }
|
|
1365
|
-
]);
|
|
1366
|
-
// ↓ 自动转换为 SQL
|
|
1367
|
-
// SELECT role, COUNT(*) as count FROM users WHERE status = 'active' GROUP BY role
|
|
1368
|
-
```
|
|
1369
|
-
|
|
1370
|
-
#### PostgreSQL 支持
|
|
1371
|
-
```javascript
|
|
1372
|
-
const db = new MonSQLize({
|
|
1373
|
-
type: 'postgres', // ← 新增支持
|
|
1374
|
-
config: {
|
|
1375
|
-
host: 'localhost',
|
|
1376
|
-
database: 'mydb'
|
|
1377
|
-
}
|
|
1378
|
-
});
|
|
1379
|
-
|
|
1380
|
-
// JSONB 字段自动映射
|
|
1381
|
-
await users.find({
|
|
1382
|
-
'metadata.tags': { $in: ['tech', 'news'] }
|
|
1383
|
-
});
|
|
1384
|
-
// ↓ 利用 PostgreSQL 的 JSONB 特性
|
|
1385
|
-
// SELECT * FROM users WHERE metadata->'tags' ?| ARRAY['tech', 'news']
|
|
1386
|
-
|
|
1387
|
-
// 数组操作
|
|
1388
|
-
await users.updateOne(
|
|
1389
|
-
{ _id: 1 },
|
|
1390
|
-
{ $push: { 'metadata.tags': 'featured' } }
|
|
1391
|
-
);
|
|
1392
|
-
// ↓ PostgreSQL 数组操作
|
|
1393
|
-
// UPDATE users SET metadata = jsonb_set(metadata, '{tags}', ...) WHERE id = 1
|
|
884
|
+
# 运行基准测试
|
|
885
|
+
npm run benchmark
|
|
1394
886
|
```
|
|
1395
887
|
|
|
1396
|
-
**技术路线**:
|
|
1397
|
-
1. **定义统一查询 AST**(抽象语法树)
|
|
1398
|
-
- MongoDB 查询 → AST → SQL 转换
|
|
1399
|
-
- 支持 90% 常用 MongoDB 操作符
|
|
1400
|
-
|
|
1401
|
-
2. **SQL 方言适配器**
|
|
1402
|
-
- MySQL: `LIMIT`, `AUTO_INCREMENT`
|
|
1403
|
-
- PostgreSQL: `JSONB`, `RETURNING`
|
|
1404
|
-
- SQL Server: `TOP`, `IDENTITY`
|
|
1405
|
-
|
|
1406
|
-
3. **保持核心功能**
|
|
1407
|
-
- 智能缓存(跨数据库)
|
|
1408
|
-
- 事务管理(适配各数据库)
|
|
1409
|
-
- 性能监控
|
|
1410
|
-
|
|
1411
|
-
4. **操作符映射表**
|
|
1412
|
-
|
|
1413
|
-
| MongoDB 操作符 | MySQL | PostgreSQL | SQL Server |
|
|
1414
|
-
|---------------|-------|------------|------------|
|
|
1415
|
-
| `$eq` (等于) | `=` | `=` | `=` |
|
|
1416
|
-
| `$ne` (不等于) | `!=` | `<>` | `<>` |
|
|
1417
|
-
| `$gt` (大于) | `>` | `>` | `>` |
|
|
1418
|
-
| `$gte` (大于等于) | `>=` | `>=` | `>=` |
|
|
1419
|
-
| `$lt` (小于) | `<` | `<` | `<` |
|
|
1420
|
-
| `$lte` (小于等于) | `<=` | `<=` | `<=` |
|
|
1421
|
-
| `$in` (在数组中) | `IN (...)` | `IN (...)` | `IN (...)` |
|
|
1422
|
-
| `$nin` (不在数组中) | `NOT IN (...)` | `NOT IN (...)` | `NOT IN (...)` |
|
|
1423
|
-
| `$regex` (正则匹配) | `REGEXP` | `~` | `LIKE` |
|
|
1424
|
-
| `$exists` (字段存在) | `IS NOT NULL` | `IS NOT NULL` | `IS NOT NULL` |
|
|
1425
|
-
| `$set` (设置字段) | `SET col = val` | `SET col = val` | `SET col = val` |
|
|
1426
|
-
| `$inc` (递增) | `SET col = col + n` | `SET col = col + n` | `SET col = col + n` |
|
|
1427
|
-
| `$unset` (删除字段) | `SET col = NULL` | `SET col = NULL` | `SET col = NULL` |
|
|
1428
|
-
| `$push` (数组添加) | `JSON_ARRAY_APPEND()` | `array_append()` | `JSON_MODIFY()` |
|
|
1429
|
-
| `$pull` (数组删除) | `JSON_REMOVE()` | `array_remove()` | `JSON_MODIFY()` |
|
|
1430
|
-
| `$addToSet` (集合添加) | `JSON_ARRAY_APPEND()` | `array_append()` | `JSON_MODIFY()` |
|
|
1431
|
-
|
|
1432
|
-
**限制说明**:
|
|
1433
|
-
- ⚠️ 某些 MongoDB 特性无法完美映射(如 `$lookup` 跨集合)
|
|
1434
|
-
- ⚠️ 性能可能不如原生 SQL(增加了转换层)
|
|
1435
|
-
- ✅ 90% 常用场景可以无缝支持
|
|
1436
|
-
|
|
1437
|
-
**预计时间**:2025 Q3-Q4
|
|
1438
|
-
|
|
1439
888
|
---
|
|
1440
889
|
|
|
1441
|
-
|
|
890
|
+
## 📄 许可证
|
|
1442
891
|
|
|
1443
|
-
|
|
1444
|
-
- 🔮 **SQL Server 支持**
|
|
1445
|
-
- 🔮 **Redis 作为主数据库**(文档存储)
|
|
1446
|
-
- 🔮 **其他 NoSQL**(Cassandra, DynamoDB)
|
|
1447
|
-
- 🔮 **混合查询**(跨数据库 Join)
|
|
1448
|
-
- 🔮 **数据库迁移工具**(MongoDB ↔ MySQL)
|
|
1449
|
-
- 🔮 **查询优化器**(自动选择最优执行计划)
|
|
892
|
+
[MIT License](./LICENSE)
|
|
1450
893
|
|
|
1451
894
|
---
|
|
1452
895
|
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
如果你对多数据库支持感兴趣,欢迎参与:
|
|
1456
|
-
|
|
1457
|
-
**贡献方式**:
|
|
1458
|
-
- 💡 **提出设计建议** - [GitHub Issues](https://github.com/vextjs/monSQLize/issues)
|
|
1459
|
-
- 🔧 **贡献代码** - [Pull Requests](https://github.com/vextjs/monSQLize/pulls)
|
|
1460
|
-
- 📖 **完善文档** - 帮助改进文档
|
|
1461
|
-
- 🧪 **提供测试用例** - 增加测试覆盖率
|
|
1462
|
-
- 🌍 **国际化** - 翻译文档到其他语言
|
|
1463
|
-
|
|
1464
|
-
**技术栈**:
|
|
1465
|
-
- Node.js 14+
|
|
1466
|
-
- MongoDB Driver
|
|
1467
|
-
- (未来) MySQL/PostgreSQL Drivers
|
|
1468
|
-
- TypeScript (类型定义)
|
|
896
|
+
## 💬 社区与支持
|
|
1469
897
|
|
|
1470
|
-
|
|
1471
|
-
-
|
|
1472
|
-
-
|
|
1473
|
-
-
|
|
898
|
+
- 📧 **Email**: support@monsqlize.dev
|
|
899
|
+
- 💬 **Issues**: [GitHub Issues](https://github.com/vextjs/monSQLize/issues)
|
|
900
|
+
- 📖 **文档**: [完整文档](./docs/INDEX.md)
|
|
901
|
+
- 🌟 **Star**: 如果觉得有用,请给我们一个 Star ⭐
|
|
1474
902
|
|
|
1475
903
|
---
|
|
1476
904
|
|
|
1477
|
-
##
|
|
1478
|
-
|
|
1479
|
-
[MIT License](./LICENSE)
|
|
905
|
+
## 🎉 快速链接
|
|
1480
906
|
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
## 🌟 Star History
|
|
907
|
+
<div align="center">
|
|
1484
908
|
|
|
1485
|
-
|
|
909
|
+
**[🚀 快速开始](#-5分钟快速开始)** ·
|
|
910
|
+
**[📚 完整文档](./docs/INDEX.md)** ·
|
|
911
|
+
**[💻 示例代码](./examples/)** ·
|
|
912
|
+
**[🐛 报告问题](https://github.com/vextjs/monSQLize/issues)** ·
|
|
913
|
+
**[⭐ Star 项目](https://github.com/vextjs/monSQLize)**
|
|
1486
914
|
|
|
1487
915
|
---
|
|
1488
916
|
|
|
1489
|
-
|
|
917
|
+
### 让 MongoDB 快 10~100 倍,从现在开始 🚀
|
|
1490
918
|
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
919
|
+
```bash
|
|
920
|
+
npm install monsqlize
|
|
921
|
+
```
|
|
1494
922
|
|
|
1495
923
|
---
|
|
1496
924
|
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
**由 ❤️ 用心打造**
|
|
1500
|
-
|
|
1501
|
-
[GitHub](https://github.com/vextjs/monSQLize) | [npm](https://www.npmjs.com/package/monsqlize) | [文档](./docs/INDEX.md) | [示例](./examples/)
|
|
925
|
+
Made with ❤️ by monSQLize Team
|
|
1502
926
|
|
|
1503
927
|
</div>
|
|
1504
928
|
|