mongoplusplus 1.0.5 → 1.0.7
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/index.d.ts +136 -54
- package/mongoplus.js +23 -13
- package/package.json +10 -1
- package/tsconfig.json +1 -0
package/index.d.ts
CHANGED
|
@@ -3,142 +3,224 @@ import mongoose = require('mongoose');
|
|
|
3
3
|
/**
|
|
4
4
|
* Mongoplus manages multiple mongoose connections and builds distributed models.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* ```
|
|
8
|
-
*
|
|
9
|
-
* const mp = new Mongoplus(['mongodb://
|
|
6
|
+
* Example:
|
|
7
|
+
* ```ts
|
|
8
|
+
* import Mongoplus from 'mongoplusplus';
|
|
9
|
+
* const mp = new Mongoplus(['mongodb://a/db','readonly:mongodb://b/db']);
|
|
10
10
|
* await mp.connectToAll();
|
|
11
|
-
* const User = mp.buildModel('User', new mp.Schema({ name: String, dbIndex: { type: Number, required: true } }));
|
|
12
|
-
* await User.write({ name: 'Alice' });
|
|
13
11
|
* ```
|
|
14
12
|
*/
|
|
15
13
|
declare class Mongoplus {
|
|
16
|
-
/** Array of connection URIs.
|
|
14
|
+
/** Array of connection URIs. Use `readonly:` prefix to mark read-only URIs. */
|
|
17
15
|
mongoURI: string[];
|
|
18
16
|
/** All mongoose connections created by `connectToAll`. */
|
|
19
17
|
allConnections: mongoose.Connection[];
|
|
20
|
-
/** Internal rotation index
|
|
18
|
+
/** Internal rotation index. */
|
|
21
19
|
currentIndex: number;
|
|
22
|
-
/** Connections
|
|
20
|
+
/** Connections created from `readonly:` URIs. */
|
|
23
21
|
static readonlydbs: mongoose.Connection[];
|
|
24
22
|
/** Models corresponding to readonly connections. */
|
|
25
23
|
static readonlymodels: any[];
|
|
26
24
|
|
|
27
25
|
/**
|
|
28
|
-
* Create
|
|
29
|
-
* @
|
|
26
|
+
* Create manager with list of URIs.
|
|
27
|
+
* @example
|
|
28
|
+
* const mp = new Mongoplus(['mongodb://a/db','readonly:mongodb://b/db']);
|
|
30
29
|
*/
|
|
31
30
|
constructor(mongoURI: string[]);
|
|
32
31
|
|
|
33
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Create a mongoose Schema.
|
|
34
|
+
* @example
|
|
35
|
+
* const schema = mp.Schema({ name: String, dbIndex: { type: Number, required: true } });
|
|
36
|
+
*/
|
|
34
37
|
Schema(schema: mongoose.SchemaDefinition | mongoose.Schema): mongoose.Schema;
|
|
35
38
|
|
|
36
|
-
/**
|
|
37
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Add an index to a schema.
|
|
41
|
+
* @example
|
|
42
|
+
* mp.addIndex(schema, { email: 1 });
|
|
43
|
+
*/
|
|
44
|
+
addIndex(schema: mongoose.Schema, indextype: any): void;
|
|
38
45
|
|
|
39
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Return next MongoDB URI in rotation.
|
|
48
|
+
*/
|
|
40
49
|
getNextMongoURI(): string;
|
|
41
50
|
|
|
42
51
|
/**
|
|
43
|
-
* Establish all connections
|
|
44
|
-
*
|
|
52
|
+
* Establish all connections. Call before `buildModel`.
|
|
53
|
+
* @returns array of `mongoose.Connection`.
|
|
45
54
|
*/
|
|
46
55
|
connectToAll(): mongoose.Connection[];
|
|
47
56
|
|
|
48
57
|
/**
|
|
49
|
-
* Build a distributed model across all connections.
|
|
50
|
-
*
|
|
58
|
+
* Build a distributed model across all connections. Schema must include `dbIndex`.
|
|
59
|
+
* @example
|
|
60
|
+
* const User = mp.buildModel('User', schema);
|
|
51
61
|
*/
|
|
52
62
|
buildModel(name: string, schema: mongoose.Schema): MongoModel;
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
/**
|
|
56
|
-
* MongoModel
|
|
57
|
-
* Methods with `InAllDatabase` perform the operation on every connection and return aggregated results.
|
|
66
|
+
* MongoModel wraps per-connection models and exposes multi-DB helpers.
|
|
58
67
|
*/
|
|
59
68
|
declare class MongoModel {
|
|
60
|
-
/**
|
|
69
|
+
/** Per-connection mongoose Model instances. */
|
|
61
70
|
model: any[];
|
|
62
71
|
/** Read-only model references. */
|
|
63
72
|
readonlydbs: any[];
|
|
64
|
-
/** Original schema
|
|
73
|
+
/** Original schema. */
|
|
65
74
|
s: mongoose.Schema;
|
|
66
|
-
/** Rotation index for `write
|
|
75
|
+
/** Rotation index for `write`. */
|
|
67
76
|
static currentIndex: number;
|
|
68
77
|
|
|
69
78
|
/**
|
|
70
|
-
*
|
|
71
|
-
* @
|
|
72
|
-
*
|
|
79
|
+
* Construct a MongoModel.
|
|
80
|
+
* @example
|
|
81
|
+
* const mm = new MongoModel([M1,M2], schema, [M2]);
|
|
73
82
|
*/
|
|
74
83
|
constructor(model: any[], s: mongoose.Schema, readonlydbs: any[]);
|
|
75
84
|
|
|
76
|
-
/**
|
|
77
|
-
*
|
|
78
|
-
* @
|
|
85
|
+
/**
|
|
86
|
+
* Run `find` on every DB and return aggregated results with timing.
|
|
87
|
+
* @example
|
|
88
|
+
* const { results, totalTime } = await User.findInAllDatabase({ active: true });
|
|
79
89
|
*/
|
|
80
90
|
findInAllDatabase(filter: any, chain?: any): Promise<any>;
|
|
81
91
|
|
|
82
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* Run aggregation pipeline on every DB and return aggregated results.
|
|
94
|
+
* @example
|
|
95
|
+
* await User.aggregateInAllDatabase([{ $match: { age: { $gt: 18 } } }]);
|
|
96
|
+
*/
|
|
83
97
|
aggregateInAllDatabase(filter: any, chain?: any): Promise<any>;
|
|
84
98
|
|
|
85
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* Write the same document to all writable DBs. Returns saved docs array.
|
|
101
|
+
* @example
|
|
102
|
+
* await User.writeInAllDatabase({ name: 'Alice' });
|
|
103
|
+
*/
|
|
86
104
|
writeInAllDatabase(data: any): Promise<any[]>;
|
|
87
105
|
|
|
88
|
-
/**
|
|
106
|
+
/**
|
|
107
|
+
* Update one matching document across all DBs.
|
|
108
|
+
* @example
|
|
109
|
+
* await User.UpdateOneInAllDatabase({ active: false }, { active: true });
|
|
110
|
+
*/
|
|
89
111
|
UpdateOneInAllDatabase(filter: any, update: any): Promise<any>;
|
|
90
112
|
|
|
91
|
-
/**
|
|
113
|
+
/**
|
|
114
|
+
* Update by id across all DBs.
|
|
115
|
+
* @example
|
|
116
|
+
* await User.UpdateByIdInAllDatabase(id, { name: 'Bob' });
|
|
117
|
+
*/
|
|
92
118
|
UpdateByIdInAllDatabase(id: any, update: any): Promise<any>;
|
|
93
119
|
|
|
94
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* Find by id in all DBs and delete.
|
|
122
|
+
* @example
|
|
123
|
+
* await User.findByIdInAllDatabaseAndDelete(id);
|
|
124
|
+
*/
|
|
95
125
|
findByIdInAllDatabaseAndDelete(id: any): Promise<any>;
|
|
96
126
|
|
|
97
|
-
/**
|
|
127
|
+
/**
|
|
128
|
+
* Find one in all DBs and delete.
|
|
129
|
+
* @example
|
|
130
|
+
* await User.findOneInAllDatabaseAndDelete({ email: 'x@example.com' });
|
|
131
|
+
*/
|
|
98
132
|
findOneInAllDatabaseAndDelete(filter: any): Promise<any>;
|
|
99
133
|
|
|
100
|
-
/**
|
|
134
|
+
/**
|
|
135
|
+
* Delete many documents matching `filter` in all databases and return aggregated results.
|
|
136
|
+
* @example
|
|
137
|
+
* await User.finManyInAllDatabaseAndDelete({ expired: true });
|
|
138
|
+
*/
|
|
139
|
+
findManyInAllDatabaseAndDelete(filter: any): Promise<any>;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Write a single document using round-robin balancing across writable DBs.
|
|
143
|
+
* @example
|
|
144
|
+
* const saved = await User.write({ name: 'Charlie' });
|
|
145
|
+
*/
|
|
101
146
|
write(data: any): Promise<any>;
|
|
102
147
|
|
|
103
148
|
/**
|
|
104
149
|
* Perform efficient bulk upserts across writable DBs.
|
|
105
|
-
* @
|
|
106
|
-
*
|
|
150
|
+
* @example
|
|
151
|
+
* await User.bulkWrite([{ id: '1', name: 'A' }], { batchSize: 500 });
|
|
107
152
|
*/
|
|
108
153
|
bulkWrite(data: any[], options?: { batchSize?: number; concurrentBatches?: boolean }): Promise<any[]>;
|
|
109
154
|
|
|
110
|
-
/**
|
|
155
|
+
/**
|
|
156
|
+
* Find a single document on a specific DB index.
|
|
157
|
+
* @example
|
|
158
|
+
* await User.findOne(0, { email: 'x' });
|
|
159
|
+
*/
|
|
111
160
|
findOne(dbIndex: number, filter: any, chain?: any): Promise<any>;
|
|
112
161
|
|
|
113
|
-
/**
|
|
162
|
+
/**
|
|
163
|
+
* Find documents on a specific DB index.
|
|
164
|
+
* @example
|
|
165
|
+
* await User.find(1, { active: true }, { limit: 10 });
|
|
166
|
+
*/
|
|
114
167
|
find(dbIndex: number, filter: any, chain?: any): Promise<any>;
|
|
115
168
|
|
|
116
|
-
/**
|
|
169
|
+
/**
|
|
170
|
+
* Find by id on a specific DB index.
|
|
171
|
+
* @example
|
|
172
|
+
* await User.findById(0, id);
|
|
173
|
+
*/
|
|
117
174
|
findById(dbIndex: number, filter: any, chain?: any): Promise<any>;
|
|
118
175
|
|
|
119
|
-
/**
|
|
176
|
+
/**
|
|
177
|
+
* Find by id and update on a specific DB index.
|
|
178
|
+
* @example
|
|
179
|
+
* await User.findByIdAndUpdate(0, id, { name: 'New' });
|
|
180
|
+
*/
|
|
120
181
|
findByIdAndUpdate(dbIndex: number, id: any, update: any): Promise<any>;
|
|
121
182
|
|
|
122
|
-
/**
|
|
183
|
+
/**
|
|
184
|
+
* Find by id and delete on a specific DB index.
|
|
185
|
+
* @example
|
|
186
|
+
* await User.findByIdAndDelete(1, id);
|
|
187
|
+
*/
|
|
123
188
|
findByIdAndDelete(dbIndex: number, id: any, update?: any): Promise<any>;
|
|
124
189
|
|
|
125
|
-
/**
|
|
190
|
+
/**
|
|
191
|
+
* Find one and update on a specific DB index.
|
|
192
|
+
* @example
|
|
193
|
+
* await User.findOneAndUpdate(0, { email: 'x' }, { active: false });
|
|
194
|
+
*/
|
|
126
195
|
findOneAndUpdate(dbIndex: number, filter: any, update: any): Promise<any>;
|
|
127
196
|
|
|
128
|
-
/**
|
|
197
|
+
/**
|
|
198
|
+
* Run aggregation on a specific DB index.
|
|
199
|
+
* @example
|
|
200
|
+
* await User.aggregate(0, [{ $group: { _id: '$country', count: { $sum: 1 } } }]);
|
|
201
|
+
*/
|
|
129
202
|
aggregate(dbIndex: number, filter: any): Promise<any>;
|
|
130
203
|
|
|
131
|
-
/**
|
|
204
|
+
/**
|
|
205
|
+
* Watch change stream on a specific DB index.
|
|
206
|
+
* @example
|
|
207
|
+
* const stream = User.watch(0);
|
|
208
|
+
*/
|
|
132
209
|
watch(dbIndex: number): any;
|
|
133
210
|
|
|
134
|
-
/**
|
|
211
|
+
/**
|
|
212
|
+
* Return the next model and its index for round-robin writes.
|
|
213
|
+
* @example
|
|
214
|
+
* const [model, idx] = User.getNextModel();
|
|
215
|
+
*/
|
|
135
216
|
getNextModel(): [any, number];
|
|
136
217
|
|
|
137
|
-
/**
|
|
218
|
+
/**
|
|
219
|
+
* Internal runner to execute many queries concurrently and return results with timing.
|
|
220
|
+
*/
|
|
138
221
|
runLargeComputations(computationPairs: any[]): Promise<{ results: any[]; totalTime: number }>;
|
|
139
222
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
export = Mongoplus;
|
|
144
|
-
|
|
223
|
+
declare namespace Mongoplus {
|
|
224
|
+
export { MongoModel };
|
|
225
|
+
}
|
|
226
|
+
export = Mongoplus;
|
package/mongoplus.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const mongoose = require('mongoose');
|
|
2
|
+
const { performance } = require('perf_hooks');
|
|
2
3
|
class Mongoplus {
|
|
3
4
|
constructor(mongoURI) {
|
|
4
5
|
|
|
@@ -104,19 +105,15 @@ class MongoModel {
|
|
|
104
105
|
async writeInAllDatabase(data) {
|
|
105
106
|
data["dbIndex"] = -1
|
|
106
107
|
const dynamicComputationPromises = [];
|
|
107
|
-
|
|
108
|
-
//this.readonlydbs.forEach((i)=>{modellist.splice(i,1,null)})
|
|
109
|
-
|
|
108
|
+
const promises = [];
|
|
110
109
|
for (let i = 0; i < this.model.length; i++) {
|
|
111
110
|
if (Mongoplus.readonlymodels.includes(this.model[i])) continue;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
const docData = Object.assign({}, data, { dbIndex: i });
|
|
112
|
+
const x = new this.model[i](docData);
|
|
113
|
+
promises.push(x.save());
|
|
117
114
|
}
|
|
118
115
|
|
|
119
|
-
return
|
|
116
|
+
return Promise.all(promises);
|
|
120
117
|
|
|
121
118
|
}
|
|
122
119
|
//==================
|
|
@@ -161,6 +158,16 @@ class MongoModel {
|
|
|
161
158
|
return await this.runLargeComputations(dynamicComputationPromises);
|
|
162
159
|
|
|
163
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Delete many documents matching `filter` in all databases and return aggregated results.
|
|
163
|
+
*/
|
|
164
|
+
async findManyInAllDatabaseAndDelete(filter) {
|
|
165
|
+
const dynamicComputationPromises = [];
|
|
166
|
+
this.model.forEach((modelRef) => {
|
|
167
|
+
dynamicComputationPromises.push({ fn: modelRef.deleteMany.bind(modelRef), params: [filter], chain: {} });
|
|
168
|
+
});
|
|
169
|
+
return await this.runLargeComputations(dynamicComputationPromises);
|
|
170
|
+
}
|
|
164
171
|
//=======================
|
|
165
172
|
async write(data) {
|
|
166
173
|
|
|
@@ -169,9 +176,7 @@ class MongoModel {
|
|
|
169
176
|
data["dbIndex"] = MongoModel.currentIndex;
|
|
170
177
|
MongoModel.currentIndex = (MongoModel.currentIndex + 1) % this.model.length;
|
|
171
178
|
if (Mongoplus.readonlymodels.includes(currentModel)) {
|
|
172
|
-
this.write(data)
|
|
173
|
-
//("This model is readonly");
|
|
174
|
-
|
|
179
|
+
return await this.write(data);
|
|
175
180
|
}
|
|
176
181
|
|
|
177
182
|
|
|
@@ -346,7 +351,7 @@ class MongoModel {
|
|
|
346
351
|
var currentModel = this.model[dbIndex]
|
|
347
352
|
|
|
348
353
|
if (chain.skip && chain.limit && chain.sort) {
|
|
349
|
-
currentModel.findOne(filter).skip(chain.skip).limit(chain.limit).sort(chain.sort)
|
|
354
|
+
return currentModel.findOne(filter).skip(chain.skip).limit(chain.limit).sort(chain.sort)
|
|
350
355
|
} else if (chain.skip && chain.limit) {
|
|
351
356
|
return currentModel.findOne(filter).skip(chain.skip).limit(chain.limit)
|
|
352
357
|
}
|
|
@@ -473,4 +478,9 @@ class MongoModel {
|
|
|
473
478
|
}
|
|
474
479
|
}
|
|
475
480
|
|
|
481
|
+
// Attach named export and default for interoperability
|
|
482
|
+
Mongoplus.MongoModel = MongoModel;
|
|
476
483
|
module.exports = Mongoplus;
|
|
484
|
+
module.exports.default = Mongoplus;
|
|
485
|
+
module.exports.MongoModel = MongoModel;
|
|
486
|
+
exports.MongoModel = MongoModel;
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoplusplus",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "load balancing of read and write operations across multiple MongoDB servers ",
|
|
5
5
|
"main": "mongoplus.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
|
+
"type": "commonjs",
|
|
7
8
|
"scripts": {
|
|
8
9
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
9
10
|
},
|
|
@@ -50,5 +51,13 @@
|
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@types/node": "^24.10.1",
|
|
52
53
|
"typescript": "^5.9.3"
|
|
54
|
+
},
|
|
55
|
+
"exports": {
|
|
56
|
+
".": {
|
|
57
|
+
"require": "./mongoplus.js",
|
|
58
|
+
"default": "./mongoplus.js",
|
|
59
|
+
"types": "./index.d.ts"
|
|
60
|
+
},
|
|
61
|
+
"./package.json": "./package.json"
|
|
53
62
|
}
|
|
54
63
|
}
|