mm_mongodb 1.5.1 → 1.5.3

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.
Files changed (4) hide show
  1. package/README.md +353 -612
  2. package/index.js +673 -430
  3. package/package.json +3 -3
  4. package/test.js +4 -5
package/README.md CHANGED
@@ -1,612 +1,353 @@
1
- # mm_mongodb
2
-
3
- MongoDB数据库操作模块,提供了简洁易用的API、缓存功能以及**完整的Redis兼容接口**。
4
-
5
- ## 项目信息
6
-
7
- - **当前版本**: 1.5.0
8
- - **更新日期**: 2024-12-23
9
- - **Gitee地址**: [https://gitee.com/qiuwenwu91/mm_mongodb](https://gitee.com/qiuwenwu91/mm_mongodb)
10
- - **Node.js 版本要求**: >= 14.0.0(推荐 16.0.0 及以上)
11
-
12
- ## 功能特点
13
-
14
- - ✅ 支持MongoDB连接池管理
15
- - ✅ 自动连接和重连机制
16
- - ✅ 事务支持
17
- - ✅ 索引管理
18
- - ✅ 缓存功能
19
- - ✅ **完整的Redis兼容API**:支持Redis风格的键值操作、列表、集合、有序集合、哈希等数据类型
20
- - ✅ 环境变量配置支持
21
- - ✅ 完善的错误处理和重试机制
22
- - ✅ 查询注入防护
23
- - ✅ 事件系统:支持监听关键操作的事件,包括操作前、操作后和错误事件
24
-
25
- ## 安装
26
-
27
- ```bash
28
- npm install mm_mongodb
29
- ```
30
-
31
- ## 配置
32
-
33
- ### 基本配置
34
-
35
- 在项目根目录创建 `config.tpl.json` 文件,配置如下:
36
-
37
- ```json
38
- {
39
- "mongodb": {
40
- "url": "mongodb://username:password@host:port/database",
41
- "poolSize": 20,
42
- "minPoolSize": 5,
43
- "maxPoolSize": 100,
44
- "waitQueueTimeoutMS": 10000,
45
- "connectTimeoutMS": 10000,
46
- "socketTimeoutMS": 45000,
47
- "authSource": "admin",
48
- "authMechanism": "DEFAULT"
49
- }
50
- }
51
- ```
52
-
53
- ### 环境变量配置
54
-
55
- 支持通过环境变量配置MongoDB连接信息,优先级高于配置文件:
56
-
57
- - `MONGO_URL`:MongoDB连接字符串
58
- - `MONGO_HOST`:MongoDB主机地址
59
- - `MONGO_PORT`:MongoDB端口
60
- - `MONGO_USERNAME`:MongoDB用户名
61
- - `MONGO_PASSWORD`:MongoDB密码
62
- - `MONGO_DATABASE`:MongoDB数据库名
63
- - `MONGO_AUTH_SOURCE`:认证源数据库
64
- - `MONGO_AUTH_MECHANISM`:认证机制
65
-
66
- ## 使用示例
67
-
68
- ### 基本使用
69
-
70
- ```javascript
71
- const { MongoDB } = require('mm_mongodb');
72
-
73
- // 创建MongoDB实例
74
- const db = new MongoDB();
75
-
76
- // 连接数据库
77
- await db.open();
78
-
79
- // 创建表
80
- await db.createTable('users');
81
-
82
- // 插入数据
83
- await db.insert('users', { name: '张三', age: 25 });
84
-
85
- // 查询数据
86
- const result = await db.get('users', { name: '张三' });
87
-
88
- // 更新数据
89
- await db.set('users', { name: '张三' }, { age: 26 });
90
-
91
- // 删除数据
92
- await db.del('users', { name: '张三' });
93
-
94
- // 关闭连接
95
- await db.close();
96
- ```
97
-
98
- ### 使用连接池
99
-
100
- ```javascript
101
- const { mongodb_admin } = require('mm_mongodb');
102
-
103
- // 获取连接池实例
104
- const db = mongodb_admin('default');
105
-
106
- // 使用连接池
107
- await db.open();
108
- const data = await db.get('users', {});
109
- ```
110
-
111
- ### 使用事务
112
-
113
- ```javascript
114
- const { MongoDB } = require('mm_mongodb');
115
- const db = new MongoDB();
116
-
117
- await db.open();
118
-
119
- // 开始事务
120
- const session = await db.startTransaction();
121
-
122
- try {
123
- // 在事务中执行操作
124
- await db.insert('users', { name: '李四', age: 30 }, { session });
125
- await db.insert('orders', { userId: '李四', amount: 100 }, { session });
126
-
127
- // 提交事务
128
- await db.commitTransaction(session);
129
- $.log.debug('事务提交成功');
130
- } catch (error) {
131
- // 回滚事务
132
- await db.rollbackTransaction(session);
133
- $.log.error('事务回滚:', error);
134
- }
135
- ```
136
-
137
- ### 创建索引
138
-
139
- ```javascript
140
- const db = new MongoDB();
141
- await db.open();
142
-
143
- // 创建普通索引
144
- await db.createIndex('users', { name: 1 }, { unique: true });
145
-
146
- // 创建TTL索引(数据过期自动删除)
147
- await db.createTTLIndex('logs', { createdAt: 1 }, 3600); // 3600秒后过期
148
- ```
149
-
150
- ## 事件系统
151
-
152
- mm_mongodb提供了完整的事件系统,允许您监听各种数据库操作的前后事件,便于进行日志记录、性能监控、数据校验等操作。
153
-
154
- ### 支持的事件
155
-
156
- | 事件名称 | 触发时机 | 事件参数 |
157
- |--------|--------|--------|
158
- | `set_before` | 在执行set操作前 | `{ table, key, value }` |
159
- | `set_after` | 在执行set操作后 | `{ table, key, value, result }` |
160
- | `set_error` | 在set操作出错时 | `{ table, key, value, error }` |
161
- | `del_before` | 在执行del操作前 | `{ table, key }` |
162
- | `del_after` | 在执行del操作后 | `{ table, key, result }` |
163
- | `del_error` | 在del操作出错时 | `{ table, key, error }` |
164
- | `add_before` | 在执行add操作前 | `{ table, key, value }` |
165
- | `add_after` | 在执行add操作后 | `{ table, key, value, result, exists }` |
166
- | `add_error` | 在add操作出错时 | `{ table, key, value, error }` |
167
-
168
- ### 事件参数说明
169
-
170
- - `table`: 操作的表名
171
- - `key`: 操作的键名
172
- - `value`: 操作的值
173
- - `result`: 操作的结果
174
- - `error`: 错误信息(仅在错误事件中)
175
- - `exists`: 键是否已存在(仅在add_after事件中)
176
-
177
- ### 使用示例
178
-
179
- ```javascript
180
- const { MongoDB } = require('mm_mongodb');
181
- const db = new MongoDB();
182
-
183
- // 连接数据库
184
- await db.open();
185
-
186
- // 监听set操作前事件
187
- db.on('set_before', (data) => {
188
- $.log.debug(`准备设置缓存: ${data.key} = ${JSON.stringify(data.value)}`);
189
- // 可以在这里进行数据校验、权限检查等
190
- });
191
-
192
- // 监听set操作后事件
193
- db.on('set_after', (data) => {
194
- $.log.debug(`缓存设置成功: ${data.key}, 结果:`, data.result);
195
- // 可以在这里记录日志、触发其他操作等
196
- });
197
-
198
- // 监听add操作后事件,特别注意exists标记
199
- db.on('add_after', (data) => {
200
- if (data.exists) {
201
- $.log.debug(`键 ${data.key} 已存在,未添加新值`);
202
- } else {
203
- $.log.debug(`成功添加新键: ${data.key}`);
204
- }
205
- });
206
-
207
- // 监听错误事件
208
- db.on('set_error', (data) => {
209
- $.log.error(`设置缓存失败: ${data.key}, 错误:`, data.error);
210
- });
211
-
212
- // 执行操作,触发事件
213
- await db.set('test_key', 'test_value');
214
-
215
- // 测试add方法的exists标记
216
- await db.add('test_key', 'another_value'); // 键已存在,exists将为true
217
- ```
218
-
219
- ### 应用场景
220
-
221
- 1. **数据校验和验证**:在操作前事件中验证数据的有效性
222
- 2. **访问控制和权限管理**:检查是否有权限执行特定操作
223
- 3. **性能监控**:记录操作执行时间,监控系统性能
224
- 4. **审计日志**:记录所有关键操作的详细信息
225
- 5. **缓存一致性维护**:在数据变更时更新相关缓存
226
- 6. **业务规则执行**:在特定操作前后执行业务逻辑
227
-
228
- ## Redis兼容API使用指南
229
-
230
- mm_mongodb提供了**完整的Redis兼容API**,使您可以使用熟悉的Redis命令与MongoDB进行交互。这对于从Redis迁移到MongoDB或在两者间切换使用非常有用。
231
-
232
- ### 快速开始
233
-
234
- ```javascript
235
- const { mongodb_cache_admin } = require('mm_mongodb');
236
-
237
- // 获取Redis兼容的缓存实例
238
- const cache = mongodb_cache_admin('default');
239
-
240
- // 连接数据库(重要:必须先连接)
241
- await cache.open();
242
-
243
- // 基本操作示例
244
- await cache.set('name', 'Redis Compatible');
245
- const value = await cache.get('name');
246
- ```
247
-
248
- ### 核心缓存方法
249
-
250
- | 方法名 | 说明 | 示例 |
251
- |-------|------|------|
252
- | `set(key, value, seconds)` | 设置键值,支持过期时间 | `await cache.set('name', 'value', 60);` |
253
- | `get(key)` | 获取键值 | `const value = await cache.get('name');` |
254
- | `del(key)` | 删除键 | `await cache.del('name');` |
255
- | `has(key)` / `exists(key)` | 判断键是否存在 | `const exists = await cache.has('name');` |
256
- | `clear(prefix)` | 清空缓存(可选前缀过滤) | `await cache.clear('temp:*');` |
257
- | `keys(pattern)` | 获取匹配的键名 | `const keys = await cache.keys('user:*');` |
258
- | `ttl(key)` | 获取剩余过期时间 | `const ttl = await cache.ttl('name');` |
259
- | `expire(key, seconds)` | 设置过期时间 | `await cache.expire('name', 60);` |
260
- | `add(key, value)` | 添加缓存(如果存在则不覆盖) | `await cache.add('counter', 1);` |
261
- | `addInt(key, value)` | 增加整数值 | `await cache.addInt('counter', 10);` |
262
- | `addFloat(key, value)` | 增加浮点数值 | `await cache.addFloat('score', 0.5);` |
263
- | `addStr(key, value)` | 追加字符串 | `await cache.addStr('message', ' World');` |
264
- | `sort(prefix, count, type)` | 排序并获取 | `const sorted = await cache.sort('user:*', 10, 'asc');` |
265
-
266
- ### 哈希表操作
267
-
268
- ```javascript
269
- // 设置哈希字段
270
- await cache.hset('user:1', 'name', '张三');
271
-
272
- // 获取哈希字段
273
- const name = await cache.hget('user:1', 'name');
274
-
275
- // 获取哈希所有字段和值
276
- const user = await cache.hgetall('user:1');
277
-
278
- // 批量设置哈希字段
279
- await cache.hmset('user:2', { name: '李四', age: 30 });
280
-
281
- // 批量获取哈希字段
282
- const values = await cache.hmget('user:2', 'name', 'age');
283
-
284
- // 删除哈希字段
285
- await cache.hdel('user:1', 'name');
286
-
287
- // 批量删除哈希字段
288
- await cache.hdelMulti('user:2', 'name', 'age');
289
-
290
- // 判断哈希字段是否存在
291
- const exists = await cache.hexists('user:1', 'name');
292
-
293
- // 获取哈希字段数量
294
- const count = await cache.hlen('user:1');
295
-
296
- // 获取哈希所有字段名
297
- const keys = await cache.hkeys('user:1');
298
-
299
- // 获取哈希所有字段值
300
- const vals = await cache.hvals('user:1');
301
- ```
302
-
303
- ### 列表操作
304
-
305
- ```javascript
306
- // 从右侧推入元素
307
- await cache.rpush('messages', '你好');
308
-
309
- // 从左侧推入元素
310
- await cache.lpush('messages', 'Hello');
311
-
312
- // 获取列表长度
313
- const length = await cache.llen('messages');
314
-
315
- // 获取列表指定范围的元素
316
- const range = await cache.lrange('messages', 0, 1); // 获取前两个元素
317
-
318
- // 获取列表指定索引的元素
319
- const message = await cache.lindex('messages', 0);
320
-
321
- // 从左侧弹出元素
322
- const firstMessage = await cache.lpop('messages');
323
-
324
- // 从右侧弹出元素
325
- const lastMessage = await cache.rpop('messages');
326
-
327
- // 修改列表指定索引的元素
328
- await cache.lset('messages', 0, 'Updated Message');
329
-
330
- // 删除列表中的元素
331
- await cache.lrem('messages', 2, 'value'); // 删除前2个值为'value'的元素
332
-
333
- // 裁剪列表
334
- await cache.ltrim('messages', 0, 4); // 保留前5个元素
335
- ```
336
-
337
- ### 集合操作
338
-
339
- ```javascript
340
- // 添加集合成员
341
- await cache.sadd('users:online', 'user1');
342
-
343
- // 批量添加集合成员
344
- await cache.saddMulti('users:online', 'user2', 'user3');
345
-
346
- // 获取集合所有成员
347
- const members = await cache.smembers('users:online');
348
-
349
- // 判断成员是否在集合中
350
- const isOnline = await cache.sismember('users:online', 'user1');
351
-
352
- // 获取集合成员数量
353
- const count = await cache.scard('users:online');
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
- $.log.debug('设置缓存前:', data);
438
- });
439
-
440
- cache.on('set_after', (data) => {
441
- $.log.debug('设置缓存后:', data);
442
- });
443
-
444
- cache.on('set_error', (data) => {
445
- $.log.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
+ [![npm version](https://img.shields.io/npm/v/mm_mongodb.svg)](https://www.npmjs.com/package/mm_mongodb)
6
+ [![License](https://img.shields.io/npm/l/mm_mongodb.svg)](https://github.com/qwwang/mm_mongodb/blob/main/LICENSE)
7
+ [![Node.js Version](https://img.shields.io/badge/node.js-%3E%3D14.0.0-brightgreen.svg)](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!