mm_mongodb 1.4.4 → 1.4.5
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/README.md +565 -231
- package/cache.js +2680 -173
- package/index.js +483 -64
- package/package.json +20 -13
- package/test.js +6 -8
package/README.md
CHANGED
|
@@ -1,231 +1,565 @@
|
|
|
1
|
-
# mm_mongodb
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## 功能特点
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
1
|
+
# mm_mongodb
|
|
2
|
+
|
|
3
|
+
MongoDB数据库操作模块,提供了简洁易用的API、缓存功能以及完整的Redis兼容接口。
|
|
4
|
+
|
|
5
|
+
## 功能特点
|
|
6
|
+
|
|
7
|
+
- 支持MongoDB连接池管理
|
|
8
|
+
- 自动连接和重连机制
|
|
9
|
+
- 事务支持
|
|
10
|
+
- 索引管理
|
|
11
|
+
- 缓存功能
|
|
12
|
+
- **Redis兼容API**:支持Redis风格的键值操作、列表、集合、哈希等数据类型
|
|
13
|
+
- 环境变量配置支持
|
|
14
|
+
- 完善的错误处理和重试机制
|
|
15
|
+
- 查询注入防护
|
|
16
|
+
- 事件系统:支持监听关键操作的事件
|
|
17
|
+
|
|
18
|
+
## 安装
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install mm_mongodb
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 配置
|
|
25
|
+
|
|
26
|
+
### 基本配置
|
|
27
|
+
|
|
28
|
+
在项目根目录创建 `config.tpl.json` 文件,配置如下:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"mongodb": {
|
|
33
|
+
"url": "mongodb://username:password@host:port/database",
|
|
34
|
+
"poolSize": 20,
|
|
35
|
+
"minPoolSize": 5,
|
|
36
|
+
"maxPoolSize": 100,
|
|
37
|
+
"waitQueueTimeoutMS": 10000,
|
|
38
|
+
"connectTimeoutMS": 10000,
|
|
39
|
+
"socketTimeoutMS": 45000,
|
|
40
|
+
"authSource": "admin",
|
|
41
|
+
"authMechanism": "DEFAULT"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 环境变量配置
|
|
47
|
+
|
|
48
|
+
支持通过环境变量配置MongoDB连接信息,优先级高于配置文件:
|
|
49
|
+
|
|
50
|
+
- `MONGO_URL`:MongoDB连接字符串
|
|
51
|
+
- `MONGO_HOST`:MongoDB主机地址
|
|
52
|
+
- `MONGO_PORT`:MongoDB端口
|
|
53
|
+
- `MONGO_USERNAME`:MongoDB用户名
|
|
54
|
+
- `MONGO_PASSWORD`:MongoDB密码
|
|
55
|
+
- `MONGO_DATABASE`:MongoDB数据库名
|
|
56
|
+
- `MONGO_AUTH_SOURCE`:认证源数据库
|
|
57
|
+
- `MONGO_AUTH_MECHANISM`:认证机制
|
|
58
|
+
|
|
59
|
+
## 使用示例
|
|
60
|
+
|
|
61
|
+
### 基本使用
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
const { MongoDB } = require('mm_mongodb');
|
|
65
|
+
|
|
66
|
+
// 创建MongoDB实例
|
|
67
|
+
const db = new MongoDB();
|
|
68
|
+
|
|
69
|
+
// 连接数据库
|
|
70
|
+
await db.open();
|
|
71
|
+
|
|
72
|
+
// 创建表
|
|
73
|
+
await db.createTable('users');
|
|
74
|
+
|
|
75
|
+
// 插入数据
|
|
76
|
+
await db.insert('users', { name: '张三', age: 25 });
|
|
77
|
+
|
|
78
|
+
// 查询数据
|
|
79
|
+
const result = await db.get('users', { name: '张三' });
|
|
80
|
+
|
|
81
|
+
// 更新数据
|
|
82
|
+
await db.set('users', { name: '张三' }, { age: 26 });
|
|
83
|
+
|
|
84
|
+
// 删除数据
|
|
85
|
+
await db.del('users', { name: '张三' });
|
|
86
|
+
|
|
87
|
+
// 关闭连接
|
|
88
|
+
await db.close();
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 使用连接池
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
const { mongodb_admin } = require('mm_mongodb');
|
|
95
|
+
|
|
96
|
+
// 获取连接池实例
|
|
97
|
+
const db = mongodb_admin('default');
|
|
98
|
+
|
|
99
|
+
// 使用连接池
|
|
100
|
+
await db.open();
|
|
101
|
+
const data = await db.get('users', {});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 使用事务
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
const { MongoDB } = require('mm_mongodb');
|
|
108
|
+
const db = new MongoDB();
|
|
109
|
+
|
|
110
|
+
await db.open();
|
|
111
|
+
|
|
112
|
+
// 开始事务
|
|
113
|
+
const session = await db.startTransaction();
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
// 在事务中执行操作
|
|
117
|
+
await db.insert('users', { name: '李四', age: 30 }, { session });
|
|
118
|
+
await db.insert('orders', { userId: '李四', amount: 100 }, { session });
|
|
119
|
+
|
|
120
|
+
// 提交事务
|
|
121
|
+
await db.commitTransaction(session);
|
|
122
|
+
console.log('事务提交成功');
|
|
123
|
+
} catch (error) {
|
|
124
|
+
// 回滚事务
|
|
125
|
+
await db.rollbackTransaction(session);
|
|
126
|
+
console.error('事务回滚:', error);
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 创建索引
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
const db = new MongoDB();
|
|
134
|
+
await db.open();
|
|
135
|
+
|
|
136
|
+
// 创建普通索引
|
|
137
|
+
await db.createIndex('users', { name: 1 }, { unique: true });
|
|
138
|
+
|
|
139
|
+
// 创建TTL索引(数据过期自动删除)
|
|
140
|
+
await db.createTTLIndex('logs', { createdAt: 1 }, 3600); // 3600秒后过期
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 缓存使用
|
|
144
|
+
|
|
145
|
+
#### 基本缓存操作
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
const { mongodb_cache_admin } = require('mm_mongodb');
|
|
149
|
+
|
|
150
|
+
// 获取缓存实例
|
|
151
|
+
const cache = mongodb_cache_admin('default');
|
|
152
|
+
|
|
153
|
+
// 连接数据库
|
|
154
|
+
await cache.open();
|
|
155
|
+
|
|
156
|
+
// 设置缓存(10秒过期)
|
|
157
|
+
await cache.set('user_1', { id: 1, name: '王五' }, 10);
|
|
158
|
+
|
|
159
|
+
// 获取缓存
|
|
160
|
+
const user = await cache.get('user_1');
|
|
161
|
+
|
|
162
|
+
// 删除缓存
|
|
163
|
+
await cache.del('user_1');
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### 数值操作
|
|
167
|
+
|
|
168
|
+
```javascript
|
|
169
|
+
// 增加整数值
|
|
170
|
+
await cache.addInt('counter', 1); // 增加1
|
|
171
|
+
|
|
172
|
+
// 增加浮点数值
|
|
173
|
+
await cache.addFloat('score', 0.5); // 增加0.5
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### 数组操作
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
// 设置数组
|
|
180
|
+
await cache.list_set('users', ['张三', '李四', '王五']);
|
|
181
|
+
|
|
182
|
+
// 添加到数组
|
|
183
|
+
await cache.list_push('users', '赵六');
|
|
184
|
+
|
|
185
|
+
// 获取数组
|
|
186
|
+
const users = await cache.list_get('users');
|
|
187
|
+
|
|
188
|
+
// 判断元素是否在数组中
|
|
189
|
+
const exists = await cache.list_has('users', '张三');
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### 过期时间管理
|
|
193
|
+
|
|
194
|
+
```javascript
|
|
195
|
+
// 设置过期时间(秒)
|
|
196
|
+
await cache.expire('temp_data', 300); // 5分钟后过期
|
|
197
|
+
|
|
198
|
+
// 获取剩余过期时间
|
|
199
|
+
const ttl = await cache.ttl('temp_data');
|
|
200
|
+
if (ttl === -1) console.log('永不过期');
|
|
201
|
+
else if (ttl === -2) console.log('键不存在');
|
|
202
|
+
else console.log(`剩余${ttl}秒过期`);
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Redis兼容API使用指南
|
|
206
|
+
|
|
207
|
+
mm_mongodb提供了完整的Redis兼容API,使您可以使用熟悉的Redis命令与MongoDB进行交互。这对于从Redis迁移到MongoDB或在两者间切换使用非常有用。
|
|
208
|
+
|
|
209
|
+
### 基本键值操作
|
|
210
|
+
|
|
211
|
+
```javascript
|
|
212
|
+
// 设置键值(支持过期时间)
|
|
213
|
+
await cache.set('name', 'Redis Compatible');
|
|
214
|
+
|
|
215
|
+
// 仅当键不存在时设置
|
|
216
|
+
await cache.setnx('counter', 1);
|
|
217
|
+
|
|
218
|
+
// 设置带过期时间的键(SET EX)
|
|
219
|
+
await cache.setex('temp_key', 60, '临时值');
|
|
220
|
+
|
|
221
|
+
// 获取键值
|
|
222
|
+
const value = await cache.get('name');
|
|
223
|
+
|
|
224
|
+
// 批量设置
|
|
225
|
+
await cache.mset({ 'key1': 'value1', 'key2': 'value2' });
|
|
226
|
+
|
|
227
|
+
// 批量获取
|
|
228
|
+
const values = await cache.mget('key1', 'key2', 'key3');
|
|
229
|
+
|
|
230
|
+
// 删除键
|
|
231
|
+
await cache.del('name');
|
|
232
|
+
|
|
233
|
+
// 批量删除键
|
|
234
|
+
await cache.delKeys('key1', 'key2');
|
|
235
|
+
|
|
236
|
+
// 判断键是否存在
|
|
237
|
+
const exists = await cache.has('name');
|
|
238
|
+
|
|
239
|
+
// 获取匹配的键名
|
|
240
|
+
const keys = await cache.keys('user:*');
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### 字符串操作
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
// 追加字符串
|
|
247
|
+
await cache.append('greeting', ' World');
|
|
248
|
+
|
|
249
|
+
// 获取字符串长度
|
|
250
|
+
const length = await cache.strlen('greeting');
|
|
251
|
+
|
|
252
|
+
// 获取字符串子串
|
|
253
|
+
const substring = await cache.getrange('greeting', 0, 4); // 获取前5个字符
|
|
254
|
+
|
|
255
|
+
// 设置字符串子串
|
|
256
|
+
await cache.setrange('greeting', 6, 'MongoDB');
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### 数值操作
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
// 原子递增
|
|
263
|
+
await cache.incr('counter'); // 自增1
|
|
264
|
+
|
|
265
|
+
// 原子递减
|
|
266
|
+
await cache.decr('counter'); // 自减1
|
|
267
|
+
|
|
268
|
+
// 增加指定整数
|
|
269
|
+
await cache.incrby('counter', 10); // 增加10
|
|
270
|
+
|
|
271
|
+
// 减少指定整数
|
|
272
|
+
await cache.decrby('counter', 5); // 减少5
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### 列表操作
|
|
276
|
+
|
|
277
|
+
```javascript
|
|
278
|
+
// 从右侧推入元素
|
|
279
|
+
await cache.rpush('list', 'item1');
|
|
280
|
+
|
|
281
|
+
// 从左侧推入元素
|
|
282
|
+
await cache.lpush('list', 'item0');
|
|
283
|
+
|
|
284
|
+
// 获取列表长度
|
|
285
|
+
const length = await cache.llen('list');
|
|
286
|
+
|
|
287
|
+
// 获取列表指定范围的元素
|
|
288
|
+
const range = await cache.lrange('list', 0, 1); // 获取前两个元素
|
|
289
|
+
|
|
290
|
+
// 获取列表指定索引的元素
|
|
291
|
+
const item = await cache.lindex('list', 0);
|
|
292
|
+
|
|
293
|
+
// 从左侧弹出元素
|
|
294
|
+
const lpop = await cache.lpop('list');
|
|
295
|
+
|
|
296
|
+
// 从右侧弹出元素
|
|
297
|
+
const rpop = await cache.rpop('list');
|
|
298
|
+
|
|
299
|
+
// 修改列表指定索引的元素
|
|
300
|
+
await cache.lset('list', 0, 'new_item');
|
|
301
|
+
|
|
302
|
+
// 删除列表中的元素
|
|
303
|
+
await cache.lrem('list', 2, 'value'); // 删除前2个值为'value'的元素
|
|
304
|
+
|
|
305
|
+
// 裁剪列表
|
|
306
|
+
await cache.ltrim('list', 0, 1); // 保留前两个元素
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### 集合操作
|
|
310
|
+
|
|
311
|
+
```javascript
|
|
312
|
+
// 添加集合成员
|
|
313
|
+
await cache.sadd('set', 'member1');
|
|
314
|
+
|
|
315
|
+
// 批量添加集合成员
|
|
316
|
+
await cache.saddMulti('set', 'member2', 'member3');
|
|
317
|
+
|
|
318
|
+
// 获取集合所有成员
|
|
319
|
+
const members = await cache.smembers('set');
|
|
320
|
+
|
|
321
|
+
// 判断成员是否在集合中
|
|
322
|
+
const isMember = await cache.sismember('set', 'member1');
|
|
323
|
+
|
|
324
|
+
// 获取集合成员数量
|
|
325
|
+
const count = await cache.scard('set');
|
|
326
|
+
|
|
327
|
+
// 移除集合成员
|
|
328
|
+
await cache.srem('set', 'member1');
|
|
329
|
+
|
|
330
|
+
// 批量移除集合成员
|
|
331
|
+
await cache.sremMulti('set', 'member2', 'member3');
|
|
332
|
+
|
|
333
|
+
// 计算两个集合的差集
|
|
334
|
+
const diff = await cache.sdiff('set1', 'set2');
|
|
335
|
+
|
|
336
|
+
// 计算两个集合的交集
|
|
337
|
+
const inter = await cache.sinter('set1', 'set2');
|
|
338
|
+
|
|
339
|
+
// 计算两个集合的并集
|
|
340
|
+
const union = await cache.sunion('set1', 'set2');
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### 哈希操作
|
|
344
|
+
|
|
345
|
+
```javascript
|
|
346
|
+
// 设置哈希字段
|
|
347
|
+
await cache.hset('hash', 'field1', 'value1');
|
|
348
|
+
|
|
349
|
+
// 获取哈希字段
|
|
350
|
+
const value = await cache.hget('hash', 'field1');
|
|
351
|
+
|
|
352
|
+
// 获取哈希所有字段和值
|
|
353
|
+
const allFields = await cache.hgetall('hash');
|
|
354
|
+
|
|
355
|
+
// 批量设置哈希字段
|
|
356
|
+
await cache.hmset('hash', { field2: 'value2', field3: 'value3' });
|
|
357
|
+
|
|
358
|
+
// 批量获取哈希字段
|
|
359
|
+
const values = await cache.hmget('hash', 'field1', 'field2', 'field3');
|
|
360
|
+
|
|
361
|
+
// 删除哈希字段
|
|
362
|
+
await cache.hdel('hash', 'field1');
|
|
363
|
+
|
|
364
|
+
// 批量删除哈希字段
|
|
365
|
+
await cache.hdelMulti('hash', 'field2', 'field3');
|
|
366
|
+
|
|
367
|
+
// 判断哈希字段是否存在
|
|
368
|
+
const exists = await cache.hexists('hash', 'field1');
|
|
369
|
+
|
|
370
|
+
// 获取哈希字段数量
|
|
371
|
+
const count = await cache.hlen('hash');
|
|
372
|
+
|
|
373
|
+
// 获取哈希所有字段名
|
|
374
|
+
const keys = await cache.hkeys('hash');
|
|
375
|
+
|
|
376
|
+
// 获取哈希所有字段值
|
|
377
|
+
const values = await cache.hvals('hash');
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### 键重命名和数据库信息
|
|
381
|
+
|
|
382
|
+
```javascript
|
|
383
|
+
// 重命名键
|
|
384
|
+
await cache.rename('old_key', 'new_key');
|
|
385
|
+
|
|
386
|
+
// 仅当新键不存在时重命名
|
|
387
|
+
const renamed = await cache.renamenx('old_key', 'new_key');
|
|
388
|
+
|
|
389
|
+
// 获取键空间大小(数据库中的键数量)
|
|
390
|
+
const size = await cache.dbsize();
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## 事件系统
|
|
394
|
+
|
|
395
|
+
mm_mongodb的缓存模块实现了事件系统,可以监听各种操作的发生。增删改类方法会触发相应的事件,而查询类方法不触发事件以提高性能。
|
|
396
|
+
|
|
397
|
+
```javascript
|
|
398
|
+
// 监听事件
|
|
399
|
+
cache.on('set_before', (data) => {
|
|
400
|
+
console.log('设置缓存前:', data);
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
cache.on('set_after', (data) => {
|
|
404
|
+
console.log('设置缓存后:', data);
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
cache.on('set_error', (data) => {
|
|
408
|
+
console.error('设置缓存错误:', data);
|
|
409
|
+
});
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### 支持事件的方法
|
|
413
|
+
|
|
414
|
+
以下增删改类方法支持事件触发:
|
|
415
|
+
|
|
416
|
+
- 原子操作:incr, decr, incrby, decrby
|
|
417
|
+
- 字符串操作:append, addStr
|
|
418
|
+
- 列表操作:rpush, lpush, lset, lrem, ltrim
|
|
419
|
+
- 集合操作:sadd, saddMulti, srem, sremMulti
|
|
420
|
+
- 哈希操作:hset, hmset, hdel, hdelMulti
|
|
421
|
+
- 键操作:set, setnx, setex, mset, del, delKeys, rename, renamenx
|
|
422
|
+
|
|
423
|
+
## 性能优化建议
|
|
424
|
+
|
|
425
|
+
1. **使用连接池**:优先使用`mongodb_admin`和`mongodb_cache_admin`创建的连接池实例
|
|
426
|
+
2. **合理设置索引**:为常用查询字段创建索引
|
|
427
|
+
3. **查询优化**:避免全表扫描,使用精确查询
|
|
428
|
+
4. **批量操作**:优先使用批量操作方法如`insertBatch`、`mget`、`mset`等
|
|
429
|
+
5. **过期时间**:为临时数据设置合理的过期时间,避免数据膨胀
|
|
430
|
+
6. **查询类方法**:注意查询类方法不触发事件,以提高查询性能
|
|
431
|
+
|
|
432
|
+
## 迁移指南
|
|
433
|
+
|
|
434
|
+
从Redis迁移到使用mm_mongodb的Redis兼容API时,只需以下步骤:
|
|
435
|
+
|
|
436
|
+
1. 安装mm_mongodb:`npm install mm_mongodb`
|
|
437
|
+
2. 修改导入语句:将Redis客户端导入改为`mongodb_cache_admin`
|
|
438
|
+
3. 添加连接初始化:调用`await cache.open()`确保连接已建立
|
|
439
|
+
4. 保持命令调用不变:大多数Redis命令可以直接使用
|
|
440
|
+
|
|
441
|
+
```javascript
|
|
442
|
+
// Redis客户端示例
|
|
443
|
+
// const redis = require('redis');
|
|
444
|
+
// const client = redis.createClient();
|
|
445
|
+
|
|
446
|
+
// mm_mongodb替换示例
|
|
447
|
+
const { mongodb_cache_admin } = require('mm_mongodb');
|
|
448
|
+
const cache = mongodb_cache_admin('default');
|
|
449
|
+
await cache.open(); // 确保连接已建立
|
|
450
|
+
|
|
451
|
+
// 后续命令调用保持不变
|
|
452
|
+
await cache.set('key', 'value');
|
|
453
|
+
const value = await cache.get('key');
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
## API文档
|
|
457
|
+
|
|
458
|
+
### MongoDB类
|
|
459
|
+
|
|
460
|
+
#### 构造函数
|
|
461
|
+
|
|
462
|
+
```javascript
|
|
463
|
+
new MongoDB(scope = 'default', dir = '', config = {})
|
|
464
|
+
```
|
|
465
|
+
- `scope`:作用域,用于区分不同的连接池
|
|
466
|
+
- `dir`:配置文件路径
|
|
467
|
+
- `config`:配置对象
|
|
468
|
+
|
|
469
|
+
#### 连接管理
|
|
470
|
+
|
|
471
|
+
- `open()`:连接数据库
|
|
472
|
+
- `close()`:关闭数据库连接
|
|
473
|
+
- `setUrl(url)`:设置连接URL
|
|
474
|
+
- `setConfig(config)`:设置配置
|
|
475
|
+
|
|
476
|
+
#### 表操作
|
|
477
|
+
|
|
478
|
+
- `createTable(tableName)`:创建表
|
|
479
|
+
- `dropTable(tableName)`:删除表
|
|
480
|
+
- `existsTable(tableName)`:检查表是否存在
|
|
481
|
+
|
|
482
|
+
#### 数据操作
|
|
483
|
+
|
|
484
|
+
- `insert(tableName, data)`:插入数据
|
|
485
|
+
- `insertBatch(tableName, datas)`:批量插入数据
|
|
486
|
+
- `get(tableName, query, options)`:查询数据
|
|
487
|
+
- `getOne(tableName, query, options)`:查询单条数据
|
|
488
|
+
- `set(tableName, query, data, options)`:修改数据
|
|
489
|
+
- `del(tableName, query, options)`:删除数据
|
|
490
|
+
- `count(tableName, query)`:统计数量
|
|
491
|
+
|
|
492
|
+
#### 事务支持
|
|
493
|
+
|
|
494
|
+
- `startTransaction()`:开始事务,返回会话对象
|
|
495
|
+
- `commitTransaction(session)`:提交事务
|
|
496
|
+
- `rollbackTransaction(session)`:回滚事务
|
|
497
|
+
|
|
498
|
+
#### 索引管理
|
|
499
|
+
|
|
500
|
+
- `createIndex(tableName, keys, options)`:创建索引
|
|
501
|
+
- `createTTLIndex(tableName, keys, expireAfterSeconds)`:创建TTL索引
|
|
502
|
+
- `getIndexes(tableName)`:获取索引信息
|
|
503
|
+
- `dropIndex(tableName, indexName)`:删除索引
|
|
504
|
+
|
|
505
|
+
### Mongodb_cache类
|
|
506
|
+
|
|
507
|
+
#### 基本操作
|
|
508
|
+
|
|
509
|
+
- `get(key)`:获取缓存
|
|
510
|
+
- `set(key, value, seconds)`:设置缓存
|
|
511
|
+
- `add(key, value, seconds)`:添加缓存(如果存在则不覆盖)
|
|
512
|
+
- `del(key)`:删除缓存
|
|
513
|
+
- `has(key)`:判断键是否存在
|
|
514
|
+
- `clear(prefix)`:清空缓存(可选前缀过滤)
|
|
515
|
+
|
|
516
|
+
#### 数值操作
|
|
517
|
+
|
|
518
|
+
- `addInt(key, value)`:增加整数值
|
|
519
|
+
- `addFloat(key, value)`:增加浮点数值
|
|
520
|
+
- `addStr(key, value)`:追加字符串
|
|
521
|
+
|
|
522
|
+
#### 数组操作
|
|
523
|
+
|
|
524
|
+
- `list_set(key, value, seconds)`:设置数组
|
|
525
|
+
- `list_push(key, value)`:添加到数组
|
|
526
|
+
- `list_get(key, start, end)`:获取数组片段
|
|
527
|
+
- `list_has(key, value)`:判断元素是否在数组中
|
|
528
|
+
- `list_clear(key, value)`:清空数组
|
|
529
|
+
|
|
530
|
+
#### 过期时间
|
|
531
|
+
|
|
532
|
+
- `expire(key, seconds)`:设置过期时间
|
|
533
|
+
- `ttl(key)`:获取剩余过期时间
|
|
534
|
+
|
|
535
|
+
#### 其他操作
|
|
536
|
+
|
|
537
|
+
- `keys(pattern)`:获取匹配的键名
|
|
538
|
+
- `getrange(key, start, end)`:获取字符串范围
|
|
539
|
+
- `setrange(key, index, value)`:设置字符串范围
|
|
540
|
+
- `sort(prefix, count, type)`:排序并获取
|
|
541
|
+
|
|
542
|
+
#### Redis兼容API
|
|
543
|
+
|
|
544
|
+
详细的Redis兼容API见上方「Redis兼容API使用指南」章节。
|
|
545
|
+
|
|
546
|
+
## 安全注意事项
|
|
547
|
+
|
|
548
|
+
1. 密码会自动进行URI编码,确保安全传输
|
|
549
|
+
2. 支持查询条件注入防护
|
|
550
|
+
3. 自动加载环境变量中的敏感信息,避免硬编码
|
|
551
|
+
4. 连接错误时会自动重试,提高稳定性
|
|
552
|
+
5. 避免使用未经处理的用户输入作为查询条件
|
|
553
|
+
|
|
554
|
+
## 依赖
|
|
555
|
+
|
|
556
|
+
- [mm_logs](https://www.npmjs.com/package/mm_logs):日志模块
|
|
557
|
+
- [mongodb](https://www.npmjs.com/package/mongodb):MongoDB官方驱动
|
|
558
|
+
|
|
559
|
+
## 作者
|
|
560
|
+
|
|
561
|
+
邱文武 - [qww.elins.cn](http://qww.elins.cn)
|
|
562
|
+
|
|
563
|
+
## 许可证
|
|
564
|
+
|
|
565
|
+
MIT
|