mm_mongodb 1.5.0 → 1.5.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/README.md +353 -612
- package/index.js +668 -428
- package/package.json +3 -3
- package/test.js +4 -5
- package/test2.js +10 -10
package/README.md
CHANGED
|
@@ -1,612 +1,353 @@
|
|
|
1
|
-
# mm_mongodb
|
|
2
|
-
|
|
3
|
-
MongoDB
|
|
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
|
-
await
|
|
78
|
-
|
|
79
|
-
//
|
|
80
|
-
await
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
//
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
//
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
// 移除集合成员
|
|
356
|
-
await cache.srem('users:online', 'user1');
|
|
357
|
-
|
|
358
|
-
// 批量移除集合成员
|
|
359
|
-
await cache.sremMulti('users:online', 'user2', 'user3');
|
|
360
|
-
|
|
361
|
-
// 计算两个集合的差集
|
|
362
|
-
const offlineUsers = await cache.sdiff('users:all', 'users:online');
|
|
363
|
-
|
|
364
|
-
// 计算两个集合的交集
|
|
365
|
-
const activeUsers = await cache.sinter('users:online', 'users:paid');
|
|
366
|
-
|
|
367
|
-
// 计算两个集合的并集
|
|
368
|
-
const allUsers = await cache.sunion('users:online', 'users:offline');
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
### 有序集合操作
|
|
372
|
-
|
|
373
|
-
```javascript
|
|
374
|
-
// 添加有序集合成员
|
|
375
|
-
await cache.zadd('ranking', 'user1', 100);
|
|
376
|
-
|
|
377
|
-
// 获取有序集合成员数量
|
|
378
|
-
const count = await cache.zcard('ranking');
|
|
379
|
-
|
|
380
|
-
// 获取有序集合成员分数
|
|
381
|
-
const score = await cache.zscore('ranking', 'user1');
|
|
382
|
-
|
|
383
|
-
// 按分数范围获取有序集合成员
|
|
384
|
-
const topUsers = await cache.zrangebyscore('ranking', 0, 100);
|
|
385
|
-
|
|
386
|
-
// 移除有序集合成员
|
|
387
|
-
await cache.zrem('ranking', 'user1');
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
### 批量操作
|
|
391
|
-
|
|
392
|
-
```javascript
|
|
393
|
-
// 批量设置键值
|
|
394
|
-
await cache.mset({ 'key1': 'value1', 'key2': 'value2' });
|
|
395
|
-
|
|
396
|
-
// 批量获取键值
|
|
397
|
-
const values = await cache.mget('key1', 'key2', 'key3');
|
|
398
|
-
|
|
399
|
-
// 批量删除键
|
|
400
|
-
await cache.del('key1', 'key2', 'key3');
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
### 数值操作
|
|
404
|
-
|
|
405
|
-
```javascript
|
|
406
|
-
// 原子递增
|
|
407
|
-
await cache.incr('counter'); // 自增1
|
|
408
|
-
|
|
409
|
-
// 原子递减
|
|
410
|
-
await cache.decr('counter'); // 自减1
|
|
411
|
-
|
|
412
|
-
// 增加指定整数
|
|
413
|
-
await cache.addInt('counter', 10); // 增加10
|
|
414
|
-
|
|
415
|
-
// 减少指定整数
|
|
416
|
-
await cache.addInt('counter', -5); // 减少5
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
## 事件系统
|
|
420
|
-
|
|
421
|
-
mm_mongodb的缓存模块实现了事件系统,可以监听各种操作的发生。增删改类方法会触发相应的事件,而查询类方法不触发事件以提高性能。
|
|
422
|
-
|
|
423
|
-
### 事件命名规范
|
|
424
|
-
|
|
425
|
-
所有事件严格遵循以下命名格式:
|
|
426
|
-
- 操作前事件:`action_before`
|
|
427
|
-
- 操作后事件:`action_after`
|
|
428
|
-
- 操作错误事件:`action_error`
|
|
429
|
-
|
|
430
|
-
其中`action`为方法名,例如`set`、`del`、`add`等。
|
|
431
|
-
|
|
432
|
-
### 事件示例
|
|
433
|
-
|
|
434
|
-
```javascript
|
|
435
|
-
// 监听事件
|
|
436
|
-
cache.on('set_before', (data) => {
|
|
437
|
-
console.log('设置缓存前:', data);
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
cache.on('set_after', (data) => {
|
|
441
|
-
console.log('设置缓存后:', data);
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
cache.on('set_error', (data) => {
|
|
445
|
-
console.error('设置缓存错误:', data);
|
|
446
|
-
});
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
### 支持事件的方法
|
|
450
|
-
|
|
451
|
-
以下增删改类方法支持事件触发,每种方法都会触发对应的`action_before`、`action_after`和`action_error`事件:
|
|
452
|
-
|
|
453
|
-
- 原子操作:incr, decr, addInt, addFloat
|
|
454
|
-
- 字符串操作:append, addStr
|
|
455
|
-
- 列表操作:rpush, lpush, lset, lrem, ltrim, lpop, rpop
|
|
456
|
-
- 集合操作:sadd, saddMulti, srem, sremMulti
|
|
457
|
-
- 哈希操作:hset, hmset, hdel, hdelMulti
|
|
458
|
-
- 有序集合操作:zadd, zrem
|
|
459
|
-
- 键操作:set, del, expire, mset, add
|
|
460
|
-
|
|
461
|
-
### 事件参数
|
|
462
|
-
|
|
463
|
-
事件回调函数接收的参数通常包含以下信息:
|
|
464
|
-
- 操作涉及的键(key)
|
|
465
|
-
- 操作涉及的值(value)
|
|
466
|
-
- 操作结果(仅在after事件中)
|
|
467
|
-
- 错误信息(仅在error事件中)
|
|
468
|
-
|
|
469
|
-
具体参数结构取决于触发事件的方法类型。
|
|
470
|
-
|
|
471
|
-
## 性能优化建议
|
|
472
|
-
|
|
473
|
-
1. **使用连接池**:优先使用`mongodb_admin`和`mongodb_cache_admin`创建的连接池实例
|
|
474
|
-
2. **合理设置索引**:为常用查询字段创建索引
|
|
475
|
-
3. **查询优化**:避免全表扫描,使用精确查询
|
|
476
|
-
4. **批量操作**:优先使用批量操作方法如`mset`、`mget`等
|
|
477
|
-
5. **过期时间**:为临时数据设置合理的过期时间,避免数据膨胀
|
|
478
|
-
6. **Redis兼容模式**:使用字符串键名可以简化操作,与Redis保持一致的使用体验
|
|
479
|
-
|
|
480
|
-
## 从Redis迁移指南
|
|
481
|
-
|
|
482
|
-
从Redis迁移到使用mm_mongodb的Redis兼容API时,只需以下步骤:
|
|
483
|
-
|
|
484
|
-
1. 安装mm_mongodb:`npm install mm_mongodb`
|
|
485
|
-
2. 修改导入语句:将Redis客户端导入改为`mongodb_cache_admin`
|
|
486
|
-
3. 添加连接初始化:调用`await cache.open()`确保连接已建立
|
|
487
|
-
4. 保持命令调用不变:大多数Redis命令可以直接使用
|
|
488
|
-
|
|
489
|
-
```javascript
|
|
490
|
-
// Redis客户端示例
|
|
491
|
-
// const redis = require('redis');
|
|
492
|
-
// const client = redis.createClient();
|
|
493
|
-
// await client.connect();
|
|
494
|
-
|
|
495
|
-
// mm_mongodb替换示例
|
|
496
|
-
const { mongodb_cache_admin } = require('mm_mongodb');
|
|
497
|
-
const cache = mongodb_cache_admin('default');
|
|
498
|
-
await cache.open(); // 确保连接已建立
|
|
499
|
-
|
|
500
|
-
// 后续命令调用保持不变
|
|
501
|
-
await cache.set('key', 'value');
|
|
502
|
-
const value = await cache.get('key');
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
## API文档
|
|
506
|
-
|
|
507
|
-
### MongoDB类
|
|
508
|
-
|
|
509
|
-
#### 构造函数
|
|
510
|
-
|
|
511
|
-
```javascript
|
|
512
|
-
new MongoDB(scope = 'default', dir = '', config = {})
|
|
513
|
-
```
|
|
514
|
-
- `scope`:作用域,用于区分不同的连接池
|
|
515
|
-
- `dir`:配置文件路径
|
|
516
|
-
- `config`:配置对象
|
|
517
|
-
|
|
518
|
-
#### 连接管理
|
|
519
|
-
|
|
520
|
-
- `open()`:连接数据库
|
|
521
|
-
- `close()`:关闭数据库连接
|
|
522
|
-
- `setUrl(url)`:设置连接URL
|
|
523
|
-
- `setConfig(config)`:设置配置
|
|
524
|
-
|
|
525
|
-
#### 表操作
|
|
526
|
-
|
|
527
|
-
- `createTable(tableName)`:创建表
|
|
528
|
-
- `dropTable(tableName)`:删除表
|
|
529
|
-
- `existsTable(tableName)`:检查表是否存在
|
|
530
|
-
|
|
531
|
-
#### 数据操作
|
|
532
|
-
|
|
533
|
-
- `insert(tableName, data)`:插入数据
|
|
534
|
-
- `insertBatch(tableName, datas)`:批量插入数据
|
|
535
|
-
- `get(tableName, query, options)`:查询数据
|
|
536
|
-
- `getOne(tableName, query, options)`:查询单条数据
|
|
537
|
-
- `set(tableName, query, data, options)`:修改数据
|
|
538
|
-
- `del(tableName, query, options)`:删除数据
|
|
539
|
-
- `count(tableName, query)`:统计数量
|
|
540
|
-
|
|
541
|
-
#### 事务支持
|
|
542
|
-
|
|
543
|
-
- `startTransaction()`:开始事务,返回会话对象
|
|
544
|
-
- `commitTransaction(session)`:提交事务
|
|
545
|
-
- `rollbackTransaction(session)`:回滚事务
|
|
546
|
-
|
|
547
|
-
#### 索引管理
|
|
548
|
-
|
|
549
|
-
- `createIndex(tableName, keys, options)`:创建索引
|
|
550
|
-
- `createTTLIndex(tableName, keys, expireAfterSeconds)`:创建TTL索引
|
|
551
|
-
- `getIndexes(tableName)`:获取索引信息
|
|
552
|
-
- `dropIndex(tableName, indexName)`:删除索引
|
|
553
|
-
|
|
554
|
-
### Redis兼容API
|
|
555
|
-
|
|
556
|
-
详细的Redis兼容API见上方「Redis兼容API使用指南」章节。支持以下类别的API:
|
|
557
|
-
|
|
558
|
-
- **核心缓存方法**:set, get, del, has, exists, clear, keys, ttl, expire等
|
|
559
|
-
- **哈希表操作**:hset, hget, hgetall, hmset, hmget, hdel, hdelMulti, hexists, hkeys, hvals, hlen等
|
|
560
|
-
- **列表操作**:rpush, lpush, lrange, lindex, llen, lpop, rpop, lset, lrem, ltrim等
|
|
561
|
-
- **集合操作**:sadd, saddMulti, srem, sremMulti, smembers, scard, sismember, sdiff, sinter, sunion等
|
|
562
|
-
- **有序集合操作**:zadd, zrem, zrangebyscore, zscore, zcard等
|
|
563
|
-
- **批量操作**:mget, mset等
|
|
564
|
-
- **数值操作**:incr, decr, addInt, addFloat等
|
|
565
|
-
|
|
566
|
-
## 安全注意事项
|
|
567
|
-
|
|
568
|
-
1. 密码会自动进行URI编码,确保安全传输
|
|
569
|
-
2. 支持查询条件注入防护
|
|
570
|
-
3. 自动加载环境变量中的敏感信息,避免硬编码
|
|
571
|
-
4. 连接错误时会自动重试,提高稳定性
|
|
572
|
-
5. 避免使用未经处理的用户输入作为查询条件
|
|
573
|
-
|
|
574
|
-
## 兼容性表格
|
|
575
|
-
|
|
576
|
-
查看详细的方法兼容性对比表格,请参考项目中的 [compatibility_table.md](https://github.com/qwwang/mm_mongodb/blob/main/compatibility_table.md) 文件。
|
|
577
|
-
|
|
578
|
-
## 依赖
|
|
579
|
-
|
|
580
|
-
- [mm_logs](https://www.npmjs.com/package/mm_logs):日志模块
|
|
581
|
-
- [mongodb](https://www.npmjs.com/package/mongodb):MongoDB官方驱动
|
|
582
|
-
|
|
583
|
-
## 作者
|
|
584
|
-
|
|
585
|
-
邱文武 - [qww.elins.cn](http://qww.elins.cn)
|
|
586
|
-
|
|
587
|
-
## 贡献指南
|
|
588
|
-
|
|
589
|
-
欢迎参与mm_mongodb项目的开发和改进!以下是贡献代码的基本步骤:
|
|
590
|
-
|
|
591
|
-
1. **Fork 仓库**:在Gitee上Fork项目到您的账户
|
|
592
|
-
2. **克隆仓库**:`git clone https://gitee.com/您的用户名/mm_mongodb.git`
|
|
593
|
-
3. **创建分支**:`git checkout -b feature/your-feature-name`
|
|
594
|
-
4. **提交更改**:`git commit -m "feat: 添加新功能描述"`
|
|
595
|
-
5. **推送分支**:`git push origin feature/your-feature-name`
|
|
596
|
-
6. **创建PR**:在Gitee上提交Pull Request
|
|
597
|
-
|
|
598
|
-
## 问题反馈
|
|
599
|
-
|
|
600
|
-
如果您在使用过程中遇到任何问题或有改进建议,请通过以下方式反馈:
|
|
601
|
-
|
|
602
|
-
- **Gitee Issues**:[https://gitee.com/qiuwenwu91/mm_mongodb/issues](https://gitee.com/qiuwenwu91/mm_mongodb/issues)
|
|
603
|
-
- **NPM 链接**:[https://www.npmjs.com/package/mm_mongodb](https://www.npmjs.com/package/mm_mongodb)
|
|
604
|
-
|
|
605
|
-
## 鸣谢
|
|
606
|
-
|
|
607
|
-
感谢所有为mm_mongodb项目做出贡献的开发者和用户!
|
|
608
|
-
|
|
609
|
-
## 相关链接
|
|
610
|
-
|
|
611
|
-
- **MongoDB 官方文档**:[https://docs.mongodb.com/](https://docs.mongodb.com/)
|
|
612
|
-
- **Node.js MongoDB 驱动**:[https://www.npmjs.com/package/mongodb](https://www.npmjs.com/package/mongodb)
|
|
1
|
+
# mm_mongodb
|
|
2
|
+
|
|
3
|
+
A powerful MongoDB database operation module with Redis-compatible API, connection pooling, and event system support.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/mm_mongodb)
|
|
6
|
+
[](https://github.com/qwwang/mm_mongodb/blob/main/LICENSE)
|
|
7
|
+
[](https://nodejs.org/)
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- ✅ **Complete Redis-compatible API** - Use familiar Redis commands with MongoDB
|
|
12
|
+
- ✅ **Connection Pool Management** - Efficient connection pooling with automatic reconnection
|
|
13
|
+
- ✅ **Transaction Support** - Full ACID transactions with session management
|
|
14
|
+
- ✅ **Event System** - Comprehensive event system for monitoring operations
|
|
15
|
+
- ✅ **Index Management** - Easy index creation and management
|
|
16
|
+
- ✅ **TTL Support** - Automatic data expiration with TTL indexes
|
|
17
|
+
- ✅ **Environment Variable Configuration** - Flexible configuration via environment variables
|
|
18
|
+
- ✅ **Query Injection Protection** - Built-in security against NoSQL injection
|
|
19
|
+
- ✅ **Performance Optimized** - Optimized for high-performance database operations
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install mm_mongodb
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
### Basic Usage
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
const { MongoDB } = require('mm_mongodb');
|
|
33
|
+
|
|
34
|
+
// Create MongoDB instance
|
|
35
|
+
const db = new MongoDB();
|
|
36
|
+
|
|
37
|
+
// Connect to database
|
|
38
|
+
await db.open();
|
|
39
|
+
|
|
40
|
+
// Create collection
|
|
41
|
+
await db.createTable('users');
|
|
42
|
+
|
|
43
|
+
// Insert data
|
|
44
|
+
await db.insert('users', { name: 'John', age: 25 });
|
|
45
|
+
|
|
46
|
+
// Query data
|
|
47
|
+
const result = await db.get('users', { name: 'John' });
|
|
48
|
+
|
|
49
|
+
// Update data
|
|
50
|
+
await db.set('users', { name: 'John' }, { age: 26 });
|
|
51
|
+
|
|
52
|
+
// Delete data
|
|
53
|
+
await db.del('users', { name: 'John' });
|
|
54
|
+
|
|
55
|
+
// Close connection
|
|
56
|
+
await db.close();
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Redis-Compatible API
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
const { mongodb_cache_admin } = require('mm_mongodb');
|
|
63
|
+
|
|
64
|
+
// Get Redis-compatible cache instance
|
|
65
|
+
const cache = mongodb_cache_admin('default');
|
|
66
|
+
|
|
67
|
+
// Connect to database
|
|
68
|
+
await cache.open();
|
|
69
|
+
|
|
70
|
+
// Use Redis-style commands
|
|
71
|
+
await cache.set('name', 'Redis Compatible');
|
|
72
|
+
const value = await cache.get('name');
|
|
73
|
+
await cache.del('name');
|
|
74
|
+
|
|
75
|
+
// Hash operations
|
|
76
|
+
await cache.hset('user:1', 'name', 'John');
|
|
77
|
+
const name = await cache.hget('user:1', 'name');
|
|
78
|
+
|
|
79
|
+
// List operations
|
|
80
|
+
await cache.lpush('messages', 'Hello');
|
|
81
|
+
await cache.rpush('messages', 'World');
|
|
82
|
+
const messages = await cache.lrange('messages', 0, -1);
|
|
83
|
+
|
|
84
|
+
// Set operations
|
|
85
|
+
await cache.sadd('users:online', 'user1', 'user2');
|
|
86
|
+
const members = await cache.smembers('users:online');
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Configuration
|
|
90
|
+
|
|
91
|
+
### Environment Variables
|
|
92
|
+
|
|
93
|
+
Configure MongoDB connection via environment variables:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
MONGO_URL=mongodb://username:password@host:port/database
|
|
97
|
+
MONGO_HOST=localhost
|
|
98
|
+
MONGO_PORT=27017
|
|
99
|
+
MONGO_USERNAME=username
|
|
100
|
+
MONGO_PASSWORD=password
|
|
101
|
+
MONGO_DATABASE=database
|
|
102
|
+
MONGO_AUTH_SOURCE=admin
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Configuration File
|
|
106
|
+
|
|
107
|
+
Create `config.tpl.json` in your project root:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"mongodb": {
|
|
112
|
+
"url": "mongodb://username:password@host:port/database",
|
|
113
|
+
"poolSize": 20,
|
|
114
|
+
"minPoolSize": 5,
|
|
115
|
+
"maxPoolSize": 100,
|
|
116
|
+
"waitQueueTimeoutMS": 10000,
|
|
117
|
+
"connectTimeoutMS": 10000,
|
|
118
|
+
"socketTimeoutMS": 45000,
|
|
119
|
+
"authSource": "admin",
|
|
120
|
+
"authMechanism": "DEFAULT"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## API Documentation
|
|
126
|
+
|
|
127
|
+
### Core MongoDB Class
|
|
128
|
+
|
|
129
|
+
#### Constructor
|
|
130
|
+
|
|
131
|
+
```javascript
|
|
132
|
+
new MongoDB(scope = 'default', dir = '', config = {})
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### Connection Management
|
|
136
|
+
|
|
137
|
+
- `open()` - Connect to database
|
|
138
|
+
- `close()` - Close database connection
|
|
139
|
+
- `setUrl(url)` - Set connection URL
|
|
140
|
+
- `setConfig(config)` - Set configuration
|
|
141
|
+
|
|
142
|
+
#### Collection Operations
|
|
143
|
+
|
|
144
|
+
- `createTable(tableName)` - Create collection
|
|
145
|
+
- `dropTable(tableName)` - Drop collection
|
|
146
|
+
- `existsTable(tableName)` - Check if collection exists
|
|
147
|
+
|
|
148
|
+
#### Data Operations
|
|
149
|
+
|
|
150
|
+
- `insert(tableName, data)` - Insert document
|
|
151
|
+
- `insertBatch(tableName, datas)` - Batch insert documents
|
|
152
|
+
- `get(tableName, query, options)` - Query documents
|
|
153
|
+
- `getOne(tableName, query, options)` - Query single document
|
|
154
|
+
- `set(tableName, query, data, options)` - Update documents
|
|
155
|
+
- `del(tableName, query, options)` - Delete documents
|
|
156
|
+
- `count(tableName, query)` - Count documents
|
|
157
|
+
|
|
158
|
+
#### Transaction Support
|
|
159
|
+
|
|
160
|
+
- `startTransaction()` - Start transaction
|
|
161
|
+
- `commitTransaction(session)` - Commit transaction
|
|
162
|
+
- `rollbackTransaction(session)` - Rollback transaction
|
|
163
|
+
|
|
164
|
+
#### Index Management
|
|
165
|
+
|
|
166
|
+
- `createIndex(tableName, keys, options)` - Create index
|
|
167
|
+
- `createTTLIndex(tableName, keys, expireAfterSeconds)` - Create TTL index
|
|
168
|
+
- `getIndexes(tableName)` - Get index information
|
|
169
|
+
- `dropIndex(tableName, indexName)` - Drop index
|
|
170
|
+
|
|
171
|
+
### Redis-Compatible API
|
|
172
|
+
|
|
173
|
+
#### Key-Value Operations
|
|
174
|
+
|
|
175
|
+
- `set(key, value, seconds)` - Set key with optional expiration
|
|
176
|
+
- `get(key)` - Get value by key
|
|
177
|
+
- `del(key)` - Delete key
|
|
178
|
+
- `has(key)` / `exists(key)` - Check if key exists
|
|
179
|
+
- `clear(prefix)` - Clear keys with optional prefix
|
|
180
|
+
- `keys(pattern)` - Get matching keys
|
|
181
|
+
- `ttl(key)` - Get time to live
|
|
182
|
+
- `expire(key, seconds)` - Set expiration time
|
|
183
|
+
- `add(key, value)` - Add key if not exists
|
|
184
|
+
|
|
185
|
+
#### Hash Operations
|
|
186
|
+
|
|
187
|
+
- `hset(key, field, value)` - Set hash field
|
|
188
|
+
- `hget(key, field)` - Get hash field
|
|
189
|
+
- `hgetall(key)` - Get all hash fields
|
|
190
|
+
- `hmset(key, object)` - Set multiple hash fields
|
|
191
|
+
- `hmget(key, ...fields)` - Get multiple hash fields
|
|
192
|
+
- `hdel(key, field)` - Delete hash field
|
|
193
|
+
- `hdelMulti(key, ...fields)` - Delete multiple hash fields
|
|
194
|
+
- `hexists(key, field)` - Check if hash field exists
|
|
195
|
+
- `hkeys(key)` - Get all hash field names
|
|
196
|
+
- `hvals(key)` - Get all hash field values
|
|
197
|
+
- `hlen(key)` - Get number of hash fields
|
|
198
|
+
|
|
199
|
+
#### List Operations
|
|
200
|
+
|
|
201
|
+
- `lpush(key, value)` - Push to left of list
|
|
202
|
+
- `rpush(key, value)` - Push to right of list
|
|
203
|
+
- `lrange(key, start, stop)` - Get list range
|
|
204
|
+
- `lindex(key, index)` - Get list element by index
|
|
205
|
+
- `llen(key)` - Get list length
|
|
206
|
+
- `lpop(key)` - Pop from left of list
|
|
207
|
+
- `rpop(key)` - Pop from right of list
|
|
208
|
+
- `lset(key, index, value)` - Set list element by index
|
|
209
|
+
- `lrem(key, count, value)` - Remove list elements
|
|
210
|
+
- `ltrim(key, start, stop)` - Trim list
|
|
211
|
+
|
|
212
|
+
#### Set Operations
|
|
213
|
+
|
|
214
|
+
- `sadd(key, ...members)` - Add set members
|
|
215
|
+
- `saddMulti(key, ...members)` - Add multiple set members
|
|
216
|
+
- `srem(key, member)` - Remove set member
|
|
217
|
+
- `sremMulti(key, ...members)` - Remove multiple set members
|
|
218
|
+
- `smembers(key)` - Get all set members
|
|
219
|
+
- `scard(key)` - Get set size
|
|
220
|
+
- `sismember(key, member)` - Check if member exists in set
|
|
221
|
+
- `sdiff(key1, key2)` - Get set difference
|
|
222
|
+
- `sinter(key1, key2)` - Get set intersection
|
|
223
|
+
- `sunion(key1, key2)` - Get set union
|
|
224
|
+
|
|
225
|
+
#### Sorted Set Operations
|
|
226
|
+
|
|
227
|
+
- `zadd(key, member, score)` - Add sorted set member
|
|
228
|
+
- `zrem(key, member)` - Remove sorted set member
|
|
229
|
+
- `zrangebyscore(key, min, max)` - Get members by score range
|
|
230
|
+
- `zscore(key, member)` - Get member score
|
|
231
|
+
- `zcard(key)` - Get sorted set size
|
|
232
|
+
|
|
233
|
+
#### Batch Operations
|
|
234
|
+
|
|
235
|
+
- `mset(object)` - Set multiple keys
|
|
236
|
+
- `mget(...keys)` - Get multiple keys
|
|
237
|
+
- `del(...keys)` - Delete multiple keys
|
|
238
|
+
|
|
239
|
+
#### Numeric Operations
|
|
240
|
+
|
|
241
|
+
- `incr(key)` - Increment by 1
|
|
242
|
+
- `decr(key)` - Decrement by 1
|
|
243
|
+
- `addInt(key, value)` - Add integer value
|
|
244
|
+
- `addFloat(key, value)` - Add float value
|
|
245
|
+
- `addStr(key, value)` - Append string
|
|
246
|
+
|
|
247
|
+
## Event System
|
|
248
|
+
|
|
249
|
+
mm_mongodb provides a comprehensive event system for monitoring database operations:
|
|
250
|
+
|
|
251
|
+
```javascript
|
|
252
|
+
const db = new MongoDB();
|
|
253
|
+
await db.open();
|
|
254
|
+
|
|
255
|
+
// Listen to operation events
|
|
256
|
+
db.on('set_before', (data) => {
|
|
257
|
+
console.log('Before set operation:', data);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
db.on('set_after', (data) => {
|
|
261
|
+
console.log('After set operation:', data);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
db.on('set_error', (data) => {
|
|
265
|
+
console.error('Set operation error:', data);
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Trigger events
|
|
269
|
+
await db.set('test_key', 'test_value');
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Supported Events
|
|
273
|
+
|
|
274
|
+
- `{action}_before` - Before operation execution
|
|
275
|
+
- `{action}_after` - After operation completion
|
|
276
|
+
- `{action}_error` - On operation error
|
|
277
|
+
|
|
278
|
+
Where `{action}` can be: `set`, `del`, `add`, `hset`, `lpush`, `sadd`, `zadd`, etc.
|
|
279
|
+
|
|
280
|
+
## Performance Optimization
|
|
281
|
+
|
|
282
|
+
1. **Use Connection Pooling** - Always use `mongodb_admin` or `mongodb_cache_admin` for connection pooling
|
|
283
|
+
2. **Create Appropriate Indexes** - Index frequently queried fields
|
|
284
|
+
3. **Use Batch Operations** - Prefer `mset`, `mget`, `insertBatch` for multiple operations
|
|
285
|
+
4. **Set Expiration Times** - Use TTL indexes for temporary data
|
|
286
|
+
5. **Optimize Queries** - Avoid full collection scans, use precise queries
|
|
287
|
+
|
|
288
|
+
## Migration from Redis
|
|
289
|
+
|
|
290
|
+
Migrating from Redis to mm_mongodb is straightforward:
|
|
291
|
+
|
|
292
|
+
```javascript
|
|
293
|
+
// Redis client (original)
|
|
294
|
+
// const redis = require('redis');
|
|
295
|
+
// const client = redis.createClient();
|
|
296
|
+
// await client.connect();
|
|
297
|
+
|
|
298
|
+
// mm_mongodb (replacement)
|
|
299
|
+
const { mongodb_cache_admin } = require('mm_mongodb');
|
|
300
|
+
const cache = mongodb_cache_admin('default');
|
|
301
|
+
await cache.open();
|
|
302
|
+
|
|
303
|
+
// Your Redis commands remain the same
|
|
304
|
+
await cache.set('key', 'value');
|
|
305
|
+
const value = await cache.get('key');
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Security Considerations
|
|
309
|
+
|
|
310
|
+
- Passwords are automatically URI-encoded for secure transmission
|
|
311
|
+
- Built-in query injection protection
|
|
312
|
+
- Environment variables for sensitive configuration
|
|
313
|
+
- Automatic connection retry for improved stability
|
|
314
|
+
- Avoid using raw user input in queries
|
|
315
|
+
|
|
316
|
+
## Dependencies
|
|
317
|
+
|
|
318
|
+
- [mm_logs](https://www.npmjs.com/package/mm_logs) - Logging module
|
|
319
|
+
- [mongodb](https://www.npmjs.com/package/mongodb) - Official MongoDB driver
|
|
320
|
+
|
|
321
|
+
## Compatibility
|
|
322
|
+
|
|
323
|
+
- **Node.js**: >= 14.0.0 (Recommended: 16.0.0+)
|
|
324
|
+
- **MongoDB**: 4.0+
|
|
325
|
+
|
|
326
|
+
## Contributing
|
|
327
|
+
|
|
328
|
+
We welcome contributions! Please follow these steps:
|
|
329
|
+
|
|
330
|
+
1. Fork the repository
|
|
331
|
+
2. Create a feature branch: `git checkout -b feature/your-feature`
|
|
332
|
+
3. Commit your changes: `git commit -m "feat: add your feature"`
|
|
333
|
+
4. Push to the branch: `git push origin feature/your-feature`
|
|
334
|
+
5. Submit a pull request
|
|
335
|
+
|
|
336
|
+
## Issues and Support
|
|
337
|
+
|
|
338
|
+
If you encounter any issues or have questions:
|
|
339
|
+
|
|
340
|
+
- **GitHub Issues**: [https://github.com/qwwang/mm_mongodb/issues](https://github.com/qwwang/mm_mongodb/issues)
|
|
341
|
+
- **NPM Package**: [https://www.npmjs.com/package/mm_mongodb](https://www.npmjs.com/package/mm_mongodb)
|
|
342
|
+
|
|
343
|
+
## License
|
|
344
|
+
|
|
345
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
346
|
+
|
|
347
|
+
## Author
|
|
348
|
+
|
|
349
|
+
Qiu Wenwu - [qww.elins.cn](http://qww.elins.cn)
|
|
350
|
+
|
|
351
|
+
## Acknowledgments
|
|
352
|
+
|
|
353
|
+
Thanks to all contributors and users who have helped improve mm_mongodb!
|