@opra/mongodb 0.32.6 → 0.33.0
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/cjs/mongo-array-service.js +212 -159
- package/cjs/mongo-collection-service.js +194 -107
- package/cjs/mongo-service.js +48 -34
- package/cjs/mongo-singleton-service.js +85 -58
- package/esm/mongo-array-service.js +213 -160
- package/esm/mongo-collection-service.js +195 -108
- package/esm/mongo-service.js +48 -34
- package/esm/mongo-singleton-service.js +86 -59
- package/package.json +4 -4
- package/types/mongo-array-service.d.ts +74 -20
- package/types/mongo-collection-service.d.ts +60 -9
- package/types/mongo-service.d.ts +22 -25
- package/types/mongo-singleton-service.d.ts +31 -7
- package/types/types.d.ts +2 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import omit from 'lodash.omit';
|
|
2
2
|
import { ObjectId } from 'mongodb';
|
|
3
|
-
import { ComplexType, NotAcceptableError,
|
|
3
|
+
import { ComplexType, NotAcceptableError, ResourceNotAvailableError } from '@opra/common';
|
|
4
4
|
import { MongoAdapter } from './mongo-adapter.js';
|
|
5
5
|
import { MongoService } from './mongo-service.js';
|
|
6
6
|
/**
|
|
@@ -34,11 +34,11 @@ export class MongoArrayService extends MongoService {
|
|
|
34
34
|
* @param {AnyId} id - The ID of the resource.
|
|
35
35
|
* @param {MongoArrayService.ExistsOptions} [options] - Optional parameters for checking resource existence.
|
|
36
36
|
* @return {Promise<void>} - A promise that resolves with no value upon success.
|
|
37
|
-
* @throws {
|
|
37
|
+
* @throws {ResourceNotAvailableError} - If the resource does not exist.
|
|
38
38
|
*/
|
|
39
39
|
async assert(documentId, id, options) {
|
|
40
40
|
if (!(await this.exists(documentId, id, options)))
|
|
41
|
-
throw new
|
|
41
|
+
throw new ResourceNotAvailableError(this.getResourceName() + '.' + this.arrayKey, documentId + '/' + id);
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
44
|
* Adds a single item into the array field.
|
|
@@ -47,18 +47,20 @@ export class MongoArrayService extends MongoService {
|
|
|
47
47
|
* @param {T} input - The item to be added to the array field.
|
|
48
48
|
* @param {MongoArrayService.CreateOptions} [options] - Optional options for the create operation.
|
|
49
49
|
* @return {Promise<PartialDTO<T>>} - A promise that resolves with the partial output of the created item.
|
|
50
|
-
* @throws {
|
|
50
|
+
* @throws {ResourceNotAvailableError} - If the parent document is not found.
|
|
51
51
|
*/
|
|
52
52
|
async create(documentId, input, options) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
const info = {
|
|
54
|
+
crud: 'create',
|
|
55
|
+
method: 'create',
|
|
56
|
+
documentId,
|
|
57
|
+
itemId: input._id,
|
|
58
|
+
input,
|
|
59
|
+
options
|
|
60
|
+
};
|
|
61
|
+
return this._intercept(() => this._create(documentId, input, options), info);
|
|
62
|
+
}
|
|
63
|
+
async _create(documentId, input, options) {
|
|
62
64
|
const encode = this.getEncoder('create');
|
|
63
65
|
const doc = encode(input, { coerce: true });
|
|
64
66
|
doc._id = doc._id || this._generateId();
|
|
@@ -66,18 +68,19 @@ export class MongoArrayService extends MongoService {
|
|
|
66
68
|
const r = await this.__updateOne(docFilter, {
|
|
67
69
|
$push: { [this.fieldName]: doc }
|
|
68
70
|
}, options);
|
|
69
|
-
if (r.
|
|
71
|
+
if (r.matchedCount) {
|
|
70
72
|
if (!options)
|
|
71
73
|
return doc;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
const id = doc[this.arrayKey];
|
|
75
|
+
const out = await this._findById(documentId, id, {
|
|
76
|
+
...options,
|
|
77
|
+
filter: undefined,
|
|
78
|
+
skip: undefined
|
|
79
|
+
});
|
|
80
|
+
if (out)
|
|
81
|
+
return out;
|
|
79
82
|
}
|
|
80
|
-
throw new
|
|
83
|
+
throw new ResourceNotAvailableError(this.getResourceName(), documentId);
|
|
81
84
|
}
|
|
82
85
|
/**
|
|
83
86
|
* Counts the number of documents in the collection that match the specified parentId and options.
|
|
@@ -88,26 +91,36 @@ export class MongoArrayService extends MongoService {
|
|
|
88
91
|
* @returns {Promise<number>} - A promise that resolves to the count of documents.
|
|
89
92
|
*/
|
|
90
93
|
async count(documentId, options) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
const info = {
|
|
95
|
+
crud: 'read',
|
|
96
|
+
method: 'count',
|
|
97
|
+
documentId,
|
|
98
|
+
options
|
|
99
|
+
};
|
|
100
|
+
return this._intercept(async () => {
|
|
101
|
+
const documentFilter = MongoAdapter.prepareFilter([
|
|
102
|
+
await this._getDocumentFilter(info)
|
|
103
|
+
]);
|
|
104
|
+
const filter = MongoAdapter.prepareFilter([
|
|
105
|
+
await this._getArrayFilter(info),
|
|
106
|
+
options?.filter
|
|
107
|
+
]);
|
|
108
|
+
return this._count(documentId, { ...options, filter, documentFilter });
|
|
109
|
+
}, info);
|
|
110
|
+
}
|
|
111
|
+
async _count(documentId, options) {
|
|
98
112
|
const matchFilter = MongoAdapter.prepareFilter([
|
|
99
113
|
MongoAdapter.prepareKeyValues(documentId, [this.collectionKey]),
|
|
100
|
-
|
|
114
|
+
options?.documentFilter
|
|
101
115
|
]);
|
|
102
116
|
const stages = [
|
|
103
117
|
{ $match: matchFilter },
|
|
104
118
|
{ $unwind: { path: "$" + this.fieldName } },
|
|
105
119
|
{ $replaceRoot: { newRoot: "$" + this.fieldName } }
|
|
106
120
|
];
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
stages.push({ $match: optionsFilter });
|
|
121
|
+
if (options?.filter) {
|
|
122
|
+
const filter = MongoAdapter.prepareFilter(options?.filter);
|
|
123
|
+
stages.push({ $match: filter });
|
|
111
124
|
}
|
|
112
125
|
stages.push({ $count: '*' });
|
|
113
126
|
const r = await this.__aggregate(stages, options);
|
|
@@ -128,22 +141,32 @@ export class MongoArrayService extends MongoService {
|
|
|
128
141
|
* @return {Promise<number>} - A Promise that resolves to the number of elements deleted (1 if successful, 0 if not).
|
|
129
142
|
*/
|
|
130
143
|
async delete(documentId, id, options) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
144
|
+
const info = {
|
|
145
|
+
crud: 'delete',
|
|
146
|
+
method: 'delete',
|
|
147
|
+
documentId,
|
|
148
|
+
itemId: id,
|
|
149
|
+
options
|
|
150
|
+
};
|
|
151
|
+
return this._intercept(async () => {
|
|
152
|
+
const documentFilter = MongoAdapter.prepareFilter([
|
|
153
|
+
await this._getDocumentFilter(info)
|
|
154
|
+
]);
|
|
155
|
+
const filter = MongoAdapter.prepareFilter([
|
|
156
|
+
await this._getArrayFilter(info),
|
|
157
|
+
options?.filter
|
|
158
|
+
]);
|
|
159
|
+
return this._delete(documentId, id, { ...options, filter, documentFilter });
|
|
160
|
+
}, info);
|
|
161
|
+
}
|
|
162
|
+
async _delete(documentId, id, options) {
|
|
139
163
|
const matchFilter = MongoAdapter.prepareFilter([
|
|
140
164
|
MongoAdapter.prepareKeyValues(documentId, [this.collectionKey]),
|
|
141
|
-
|
|
165
|
+
options?.documentFilter
|
|
142
166
|
]);
|
|
143
167
|
const pullFilter = MongoAdapter.prepareFilter([
|
|
144
168
|
MongoAdapter.prepareKeyValues(id, [this.arrayKey]),
|
|
145
|
-
options?.filter
|
|
146
|
-
await this._getArrayFilter()
|
|
169
|
+
options?.filter
|
|
147
170
|
]) || {};
|
|
148
171
|
const r = await this.__updateOne(matchFilter, {
|
|
149
172
|
$pull: { [this.fieldName]: pullFilter }
|
|
@@ -158,23 +181,31 @@ export class MongoArrayService extends MongoService {
|
|
|
158
181
|
* @returns {Promise<number>} - A Promise that resolves to the number of items deleted.
|
|
159
182
|
*/
|
|
160
183
|
async deleteMany(documentId, options) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
184
|
+
const info = {
|
|
185
|
+
crud: 'delete',
|
|
186
|
+
method: 'deleteMany',
|
|
187
|
+
documentId,
|
|
188
|
+
options
|
|
189
|
+
};
|
|
190
|
+
return this._intercept(async () => {
|
|
191
|
+
const documentFilter = MongoAdapter.prepareFilter([
|
|
192
|
+
await this._getDocumentFilter(info)
|
|
193
|
+
]);
|
|
194
|
+
const filter = MongoAdapter.prepareFilter([
|
|
195
|
+
await this._getArrayFilter(info),
|
|
196
|
+
options?.filter
|
|
197
|
+
]);
|
|
198
|
+
return this._deleteMany(documentId, { ...options, filter, documentFilter });
|
|
199
|
+
}, info);
|
|
200
|
+
}
|
|
201
|
+
async _deleteMany(documentId, options) {
|
|
168
202
|
const matchFilter = MongoAdapter.prepareFilter([
|
|
169
203
|
MongoAdapter.prepareKeyValues(documentId, [this.collectionKey]),
|
|
170
|
-
|
|
204
|
+
options?.documentFilter
|
|
171
205
|
]);
|
|
172
206
|
// Count matching items, we will use this as result
|
|
173
207
|
const matchCount = await this.count(documentId, options);
|
|
174
|
-
const pullFilter = MongoAdapter.prepareFilter(
|
|
175
|
-
options?.filter,
|
|
176
|
-
await this._getArrayFilter()
|
|
177
|
-
]) || {};
|
|
208
|
+
const pullFilter = MongoAdapter.prepareFilter(options?.filter) || {};
|
|
178
209
|
const r = await this.__updateOne(matchFilter, {
|
|
179
210
|
$pull: { [this.fieldName]: pullFilter }
|
|
180
211
|
}, options);
|
|
@@ -191,15 +222,7 @@ export class MongoArrayService extends MongoService {
|
|
|
191
222
|
* @returns {Promise<boolean>} - A promise that resolves to a boolean indicating if the record exists or not.
|
|
192
223
|
*/
|
|
193
224
|
async exists(documentId, id, options) {
|
|
194
|
-
|
|
195
|
-
return this.$interceptor(() => this.exists(documentId, id, { ...options, __interceptor__: true }), {
|
|
196
|
-
crud: 'read',
|
|
197
|
-
method: 'exists',
|
|
198
|
-
documentId,
|
|
199
|
-
itemId: id,
|
|
200
|
-
options
|
|
201
|
-
}, this);
|
|
202
|
-
return !!(await this.findById(documentId, id, { ...options, pick: ['_id'] }));
|
|
225
|
+
return !!(await this.findById(documentId, id, { ...options, pick: ['_id'], omit: undefined, include: undefined }));
|
|
203
226
|
}
|
|
204
227
|
/**
|
|
205
228
|
* Finds an element in array field by its parent ID and ID.
|
|
@@ -210,19 +233,37 @@ export class MongoArrayService extends MongoService {
|
|
|
210
233
|
* @returns {Promise<PartialDTO<T> | undefined>} - A promise that resolves to the found document or undefined if not found.
|
|
211
234
|
*/
|
|
212
235
|
async findById(documentId, id, options) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
236
|
+
const info = {
|
|
237
|
+
crud: 'read',
|
|
238
|
+
method: 'findById',
|
|
239
|
+
documentId,
|
|
240
|
+
itemId: id,
|
|
241
|
+
options
|
|
242
|
+
};
|
|
243
|
+
return this._intercept(async () => {
|
|
244
|
+
const documentFilter = MongoAdapter.prepareFilter([
|
|
245
|
+
await this._getDocumentFilter(info)
|
|
246
|
+
]);
|
|
247
|
+
const filter = MongoAdapter.prepareFilter([
|
|
248
|
+
await this._getArrayFilter(info),
|
|
249
|
+
options?.filter
|
|
250
|
+
]);
|
|
251
|
+
return this._findById(documentId, id, { ...options, filter, documentFilter });
|
|
252
|
+
}, info);
|
|
253
|
+
}
|
|
254
|
+
async _findById(documentId, id, options) {
|
|
221
255
|
const filter = MongoAdapter.prepareFilter([
|
|
222
256
|
MongoAdapter.prepareKeyValues(id, [this.arrayKey]),
|
|
223
257
|
options?.filter
|
|
224
258
|
]);
|
|
225
|
-
|
|
259
|
+
const rows = await this._findMany(documentId, {
|
|
260
|
+
...options,
|
|
261
|
+
filter,
|
|
262
|
+
limit: 1,
|
|
263
|
+
skip: undefined,
|
|
264
|
+
sort: undefined
|
|
265
|
+
});
|
|
266
|
+
return rows?.[0];
|
|
226
267
|
}
|
|
227
268
|
/**
|
|
228
269
|
* Finds the first array element that matches the given parentId.
|
|
@@ -232,14 +273,25 @@ export class MongoArrayService extends MongoService {
|
|
|
232
273
|
* @returns {Promise<PartialDTO<T> | undefined>} A promise that resolves to the first matching document, or `undefined` if no match is found.
|
|
233
274
|
*/
|
|
234
275
|
async findOne(documentId, options) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
276
|
+
const info = {
|
|
277
|
+
crud: 'read',
|
|
278
|
+
method: 'findOne',
|
|
279
|
+
documentId,
|
|
280
|
+
options
|
|
281
|
+
};
|
|
282
|
+
return this._intercept(async () => {
|
|
283
|
+
const documentFilter = MongoAdapter.prepareFilter([
|
|
284
|
+
await this._getDocumentFilter(info)
|
|
285
|
+
]);
|
|
286
|
+
const filter = MongoAdapter.prepareFilter([
|
|
287
|
+
await this._getArrayFilter(info),
|
|
288
|
+
options?.filter
|
|
289
|
+
]);
|
|
290
|
+
return this._findOne(documentId, { ...options, filter, documentFilter });
|
|
291
|
+
}, info);
|
|
292
|
+
}
|
|
293
|
+
async _findOne(documentId, options) {
|
|
294
|
+
const rows = await this._findMany(documentId, {
|
|
243
295
|
...options,
|
|
244
296
|
limit: 1
|
|
245
297
|
});
|
|
@@ -253,16 +305,22 @@ export class MongoArrayService extends MongoService {
|
|
|
253
305
|
* @returns {Promise<PartialDTO<T>[]>} - The found documents.
|
|
254
306
|
*/
|
|
255
307
|
async findMany(documentId, options) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
308
|
+
const args = {
|
|
309
|
+
crud: 'read',
|
|
310
|
+
method: 'findMany',
|
|
311
|
+
documentId,
|
|
312
|
+
options
|
|
313
|
+
};
|
|
314
|
+
return this._intercept(async () => {
|
|
315
|
+
const documentFilter = await this._getDocumentFilter(args);
|
|
316
|
+
const arrayFilter = await this._getArrayFilter(args);
|
|
317
|
+
return this._findMany(documentId, { ...options, documentFilter, arrayFilter });
|
|
318
|
+
}, args);
|
|
319
|
+
}
|
|
320
|
+
async _findMany(documentId, options) {
|
|
263
321
|
const matchFilter = MongoAdapter.prepareFilter([
|
|
264
322
|
MongoAdapter.prepareKeyValues(documentId, [this.collectionKey]),
|
|
265
|
-
|
|
323
|
+
options.documentFilter
|
|
266
324
|
]);
|
|
267
325
|
const mongoOptions = {
|
|
268
326
|
...omit(options, ['pick', 'include', 'omit', 'sort', 'skip', 'limit', 'filter', 'count'])
|
|
@@ -283,11 +341,10 @@ export class MongoArrayService extends MongoService {
|
|
|
283
341
|
}
|
|
284
342
|
});
|
|
285
343
|
}
|
|
286
|
-
|
|
287
|
-
if (options?.filter || contextArrayFilter) {
|
|
344
|
+
if (options?.filter || options.arrayFilter) {
|
|
288
345
|
const optionsFilter = MongoAdapter.prepareFilter([
|
|
289
346
|
options?.filter,
|
|
290
|
-
|
|
347
|
+
options.arrayFilter
|
|
291
348
|
]);
|
|
292
349
|
dataStages.push({ $match: optionsFilter });
|
|
293
350
|
}
|
|
@@ -328,12 +385,12 @@ export class MongoArrayService extends MongoService {
|
|
|
328
385
|
* @param {AnyId} id - The ID of the item.
|
|
329
386
|
* @param {MongoArrayService.FindOneOptions<T>} [options] - The options for finding the item.
|
|
330
387
|
* @returns {Promise<PartialDTO<T>>} - The item found.
|
|
331
|
-
* @throws {
|
|
388
|
+
* @throws {ResourceNotAvailableError} - If the item is not found.
|
|
332
389
|
*/
|
|
333
390
|
async get(documentId, id, options) {
|
|
334
391
|
const out = await this.findById(documentId, id, options);
|
|
335
392
|
if (!out)
|
|
336
|
-
throw new
|
|
393
|
+
throw new ResourceNotAvailableError(this.getResourceName() + '.' + this.arrayKey, documentId + '/' + id);
|
|
337
394
|
return out;
|
|
338
395
|
}
|
|
339
396
|
/**
|
|
@@ -347,24 +404,13 @@ export class MongoArrayService extends MongoService {
|
|
|
347
404
|
* @throws {Error} If an error occurs while updating the item.
|
|
348
405
|
*/
|
|
349
406
|
async update(documentId, id, input, options) {
|
|
350
|
-
if (this.$interceptor && !options?.__interceptor__)
|
|
351
|
-
return this.$interceptor(() => this.update(documentId, id, input, { ...options, __interceptor__: true }), {
|
|
352
|
-
crud: 'update',
|
|
353
|
-
method: 'update',
|
|
354
|
-
documentId,
|
|
355
|
-
itemId: id,
|
|
356
|
-
options
|
|
357
|
-
}, this);
|
|
358
407
|
const r = await this.updateOnly(documentId, id, input, options);
|
|
359
408
|
if (!r)
|
|
360
409
|
return;
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
Error.captureStackTrace(e);
|
|
366
|
-
throw e;
|
|
367
|
-
}
|
|
410
|
+
const out = await this._findById(documentId, id, options);
|
|
411
|
+
if (out)
|
|
412
|
+
return out;
|
|
413
|
+
throw new ResourceNotAvailableError(this.getResourceName() + '.' + this.arrayKey, documentId + '/' + id);
|
|
368
414
|
}
|
|
369
415
|
/**
|
|
370
416
|
* Update an array element with new data. Returns 1 if document updated 0 otherwise.
|
|
@@ -376,19 +422,29 @@ export class MongoArrayService extends MongoService {
|
|
|
376
422
|
* @returns {Promise<number>} - A promise that resolves to the number of elements updated.
|
|
377
423
|
*/
|
|
378
424
|
async updateOnly(documentId, id, input, options) {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
425
|
+
const info = {
|
|
426
|
+
crud: 'update',
|
|
427
|
+
method: 'update',
|
|
428
|
+
documentId,
|
|
429
|
+
itemId: id,
|
|
430
|
+
options
|
|
431
|
+
};
|
|
432
|
+
return this._intercept(async () => {
|
|
433
|
+
const documentFilter = MongoAdapter.prepareFilter([
|
|
434
|
+
await this._getDocumentFilter(info)
|
|
435
|
+
]);
|
|
436
|
+
const filter = MongoAdapter.prepareFilter([
|
|
437
|
+
await this._getArrayFilter(info),
|
|
438
|
+
options?.filter
|
|
439
|
+
]);
|
|
440
|
+
return this._updateOnly(documentId, id, input, { ...options, filter, documentFilter });
|
|
441
|
+
}, info);
|
|
442
|
+
}
|
|
443
|
+
async _updateOnly(documentId, id, input, options) {
|
|
388
444
|
let filter = MongoAdapter.prepareKeyValues(id, [this.arrayKey]);
|
|
389
445
|
if (options?.filter)
|
|
390
446
|
filter = MongoAdapter.prepareFilter([filter, options?.filter]);
|
|
391
|
-
return await this.
|
|
447
|
+
return await this._updateMany(documentId, input, { ...options, filter });
|
|
392
448
|
}
|
|
393
449
|
/**
|
|
394
450
|
* Updates multiple array elements in document
|
|
@@ -399,56 +455,48 @@ export class MongoArrayService extends MongoService {
|
|
|
399
455
|
* @returns {Promise<number>} - A promise that resolves to the number of documents updated.
|
|
400
456
|
*/
|
|
401
457
|
async updateMany(documentId, input, options) {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
458
|
+
const info = {
|
|
459
|
+
crud: 'update',
|
|
460
|
+
method: 'updateMany',
|
|
461
|
+
documentId,
|
|
462
|
+
input,
|
|
463
|
+
options
|
|
464
|
+
};
|
|
465
|
+
return this._intercept(async () => {
|
|
466
|
+
const documentFilter = MongoAdapter.prepareFilter([
|
|
467
|
+
await this._getDocumentFilter(info)
|
|
468
|
+
]);
|
|
469
|
+
const filter = MongoAdapter.prepareFilter([
|
|
470
|
+
await this._getArrayFilter(info),
|
|
471
|
+
options?.filter
|
|
472
|
+
]);
|
|
473
|
+
return this._updateMany(documentId, input, { ...options, filter, documentFilter });
|
|
474
|
+
}, info);
|
|
475
|
+
}
|
|
476
|
+
async _updateMany(documentId, input, options) {
|
|
410
477
|
const encode = this.getEncoder('update');
|
|
411
478
|
const doc = encode(input, { coerce: true });
|
|
412
479
|
if (!Object.keys(doc).length)
|
|
413
480
|
return 0;
|
|
414
481
|
const matchFilter = MongoAdapter.prepareFilter([
|
|
415
482
|
MongoAdapter.prepareKeyValues(documentId, [this.collectionKey]),
|
|
416
|
-
|
|
483
|
+
options?.documentFilter,
|
|
417
484
|
{ [this.fieldName]: { $exists: true } }
|
|
418
485
|
]);
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
const elemMatch = MongoAdapter.prepareFilter([options?.filter, contextArrayFilter], { fieldPrefix: 'elem.' });
|
|
486
|
+
if (options?.filter) {
|
|
487
|
+
const elemMatch = MongoAdapter.prepareFilter([options?.filter], { fieldPrefix: 'elem.' });
|
|
422
488
|
options = options || {};
|
|
423
489
|
options.arrayFilters = [elemMatch];
|
|
424
490
|
}
|
|
425
491
|
const update = MongoAdapter.preparePatch(doc, {
|
|
426
|
-
fieldPrefix: this.fieldName + (
|
|
492
|
+
fieldPrefix: this.fieldName + (options?.filter ? '.$[elem].' : '.$[].')
|
|
427
493
|
});
|
|
428
494
|
const r = await this.__updateOne(matchFilter, update, options);
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
* Updates multiple elements and returns the count of elements that were updated.
|
|
433
|
-
*
|
|
434
|
-
* @param {AnyId} documentId - The ID of the document to update.
|
|
435
|
-
* @param {PatchDTO<T>} input - The partial document to update with.
|
|
436
|
-
* @param {MongoArrayService.UpdateManyOptions<T>} [options] - The options for updating multiple documents.
|
|
437
|
-
* @return {Promise<number>} A promise that resolves to the number of elements updated.
|
|
438
|
-
*/
|
|
439
|
-
async updateManyReturnCount(documentId, input, options) {
|
|
440
|
-
if (this.$interceptor && !options?.__interceptor__)
|
|
441
|
-
return this.$interceptor(() => this.updateManyReturnCount(documentId, input, { ...options, __interceptor__: true }), {
|
|
442
|
-
crud: 'update',
|
|
443
|
-
method: 'updateManyReturnCount',
|
|
444
|
-
documentId,
|
|
445
|
-
input,
|
|
446
|
-
options
|
|
447
|
-
}, this);
|
|
448
|
-
const r = await this.updateMany(documentId, input, options);
|
|
449
|
-
return r
|
|
495
|
+
if (!options?.count)
|
|
496
|
+
return r.modifiedCount;
|
|
497
|
+
return r.modifiedCount
|
|
450
498
|
// Count matching items that fits filter criteria
|
|
451
|
-
? await this.
|
|
499
|
+
? await this._count(documentId, options)
|
|
452
500
|
: 0;
|
|
453
501
|
}
|
|
454
502
|
/**
|
|
@@ -482,9 +530,9 @@ export class MongoArrayService extends MongoService {
|
|
|
482
530
|
* @returns {FilterInput | Promise<FilterInput> | undefined} The common filter or a Promise
|
|
483
531
|
* that resolves to the common filter, or undefined if not available.
|
|
484
532
|
*/
|
|
485
|
-
_getDocumentFilter() {
|
|
533
|
+
_getDocumentFilter(args) {
|
|
486
534
|
return typeof this.$documentFilter === 'function' ?
|
|
487
|
-
this.$documentFilter(this) : this.$documentFilter;
|
|
535
|
+
this.$documentFilter(args, this) : this.$documentFilter;
|
|
488
536
|
}
|
|
489
537
|
/**
|
|
490
538
|
* Retrieves the common filter used for querying array elements.
|
|
@@ -494,8 +542,13 @@ export class MongoArrayService extends MongoService {
|
|
|
494
542
|
* @returns {FilterInput | Promise<FilterInput> | undefined} The common filter or a Promise
|
|
495
543
|
* that resolves to the common filter, or undefined if not available.
|
|
496
544
|
*/
|
|
497
|
-
_getArrayFilter() {
|
|
545
|
+
_getArrayFilter(args) {
|
|
498
546
|
return typeof this.$arrayFilter === 'function' ?
|
|
499
|
-
this.$arrayFilter(this) : this.$arrayFilter;
|
|
547
|
+
this.$arrayFilter(args, this) : this.$arrayFilter;
|
|
548
|
+
}
|
|
549
|
+
async _intercept(callback, args) {
|
|
550
|
+
if (this.$interceptor)
|
|
551
|
+
return this.$interceptor(callback, args, this);
|
|
552
|
+
return callback();
|
|
500
553
|
}
|
|
501
554
|
}
|