@travetto/model-mongo 8.0.3 → 8.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +2 -2
- package/src/service.ts +36 -47
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ Supported features:
|
|
|
21
21
|
* [CRUD](https://github.com/travetto/travetto/tree/main/module/model/src/types/crud.ts#L10)
|
|
22
22
|
* [Expiry](https://github.com/travetto/travetto/tree/main/module/model/src/types/expiry.ts#L10)
|
|
23
23
|
* [Indexed](https://github.com/travetto/travetto/tree/main/module/model-indexed/src/types/service.ts#L21)
|
|
24
|
-
* [Aggregate](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/aggregate.ts#
|
|
24
|
+
* [Aggregate](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/aggregate.ts#L56)
|
|
25
25
|
* [Query Crud](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/crud.ts#L11)
|
|
26
26
|
* [Facet](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/facet.ts#L14)
|
|
27
27
|
* [Suggest](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/suggest.ts#L12)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model-mongo",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.5",
|
|
4
4
|
"description": "Mongo backing for the travetto model module.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"database",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@travetto/config": "^8.0.3",
|
|
33
33
|
"@travetto/model": "^8.0.3",
|
|
34
34
|
"@travetto/model-indexed": "^8.0.3",
|
|
35
|
-
"@travetto/model-query": "^8.0.
|
|
35
|
+
"@travetto/model-query": "^8.0.5",
|
|
36
36
|
"mongodb": "^7.6.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
package/src/service.ts
CHANGED
|
@@ -51,9 +51,7 @@ import {
|
|
|
51
51
|
type SortedIndexSelectionType
|
|
52
52
|
} from '@travetto/model-indexed';
|
|
53
53
|
import {
|
|
54
|
-
type
|
|
55
|
-
type AggregateOperation,
|
|
56
|
-
type AggregateResultType,
|
|
54
|
+
type FieldAggregateResult,
|
|
57
55
|
type ModelQuery,
|
|
58
56
|
type ModelQueryAggregateSupport,
|
|
59
57
|
ModelQueryAggregateUtil,
|
|
@@ -65,10 +63,10 @@ import {
|
|
|
65
63
|
ModelQuerySuggestUtil,
|
|
66
64
|
type ModelQuerySupport,
|
|
67
65
|
ModelQueryUtil,
|
|
66
|
+
type NumberFieldAggregateResult,
|
|
68
67
|
type PageableModelQuery,
|
|
69
68
|
QueryVerifier,
|
|
70
69
|
type ValidComparableFields,
|
|
71
|
-
type ValidNumericFields,
|
|
72
70
|
type ValidStringFields,
|
|
73
71
|
type WhereClause
|
|
74
72
|
} from '@travetto/model-query';
|
|
@@ -82,10 +80,10 @@ import {
|
|
|
82
80
|
type Class,
|
|
83
81
|
castTo,
|
|
84
82
|
JSONUtil,
|
|
85
|
-
RuntimeError,
|
|
86
83
|
ShutdownManager,
|
|
87
84
|
TypedObject
|
|
88
85
|
} from '@travetto/runtime';
|
|
86
|
+
import { SchemaRegistryIndex } from '@travetto/schema';
|
|
89
87
|
|
|
90
88
|
import type { MongoModelConfig } from './config.ts';
|
|
91
89
|
import { MongoUtil, type WithId } from './internal/util.ts';
|
|
@@ -641,11 +639,19 @@ export class MongoModelService
|
|
|
641
639
|
return await Promise.all(items.map(item => this.postLoad(cls, item)));
|
|
642
640
|
}
|
|
643
641
|
|
|
644
|
-
async
|
|
642
|
+
async getByQuery<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>, failOnMany = true): Promise<T> {
|
|
645
643
|
const results = await this.query<T>(cls, { ...query, limit: failOnMany ? 2 : 1 });
|
|
646
644
|
return ModelQueryUtil.verifyGetSingleCounts<T>(cls, failOnMany, results, query.where);
|
|
647
645
|
}
|
|
648
646
|
|
|
647
|
+
async countByQuery<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>): Promise<number> {
|
|
648
|
+
await QueryVerifier.verify(cls, query);
|
|
649
|
+
|
|
650
|
+
const col = await this.getStore(cls);
|
|
651
|
+
const filter = MongoUtil.extractWhereFilter(cls, query.where);
|
|
652
|
+
return col.countDocuments(filter);
|
|
653
|
+
}
|
|
654
|
+
|
|
649
655
|
// Query Crud
|
|
650
656
|
async updateByQuery<T extends ModelType>(cls: Class<T>, data: T, query: ModelQuery<T>): Promise<T> {
|
|
651
657
|
await QueryVerifier.verify(cls, query);
|
|
@@ -730,59 +736,42 @@ export class MongoModelService
|
|
|
730
736
|
.toSorted((a, b) => b.count - a.count);
|
|
731
737
|
}
|
|
732
738
|
|
|
733
|
-
static readonly AGGREGATE_OPERATION_MAPPING: Record<AggregateOperation, '$sum' | '$avg' | '$min' | '$max'> = {
|
|
734
|
-
sum: '$sum',
|
|
735
|
-
avg: '$avg',
|
|
736
|
-
min: '$min',
|
|
737
|
-
max: '$max'
|
|
738
|
-
};
|
|
739
|
-
|
|
740
739
|
// Aggregate
|
|
741
|
-
async aggregateFieldByQuery<
|
|
742
|
-
T
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
await QueryVerifier.verify(
|
|
740
|
+
async aggregateFieldByQuery<T extends ModelType, const F extends ValidComparableFields<T>>(
|
|
741
|
+
cls: Class<T>,
|
|
742
|
+
field: F,
|
|
743
|
+
query?: ModelQuery<T>
|
|
744
|
+
): Promise<FieldAggregateResult<T, F>> {
|
|
745
|
+
await QueryVerifier.verify(cls, query);
|
|
747
746
|
|
|
748
|
-
const collection = await this.getStore(
|
|
747
|
+
const collection = await this.getStore(cls);
|
|
749
748
|
|
|
750
|
-
const where = ModelQueryUtil.getWhereClause(
|
|
749
|
+
const where = ModelQueryUtil.getWhereClause(cls, query?.where);
|
|
751
750
|
let queryObject: Record<string, unknown> = { [field]: { $exists: true, $ne: null } };
|
|
752
751
|
|
|
753
752
|
if (where) {
|
|
754
|
-
queryObject = { $and: [queryObject, MongoUtil.extractWhereFilter(
|
|
753
|
+
queryObject = { $and: [queryObject, MongoUtil.extractWhereFilter(cls, where)] };
|
|
755
754
|
}
|
|
756
755
|
|
|
757
|
-
const
|
|
758
|
-
if (!aggregateOperator) {
|
|
759
|
-
throw new RuntimeError(`Unsupported aggregate operation: ${operation}`);
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
const aggregations: object[] = [
|
|
763
|
-
{ $match: queryObject },
|
|
764
|
-
{
|
|
765
|
-
$group: {
|
|
766
|
-
_id: null,
|
|
767
|
-
value: {
|
|
768
|
-
[aggregateOperator]: `$${String(field)}`
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
];
|
|
756
|
+
const isDate = SchemaRegistryIndex.getNestedFieldConfig(cls, field)!.type === Date;
|
|
773
757
|
|
|
774
|
-
const
|
|
775
|
-
|
|
758
|
+
const groupFields: Record<string, unknown> = {
|
|
759
|
+
_id: null,
|
|
760
|
+
count: { $sum: 1 },
|
|
761
|
+
min: { $min: `$${String(field)}` },
|
|
762
|
+
max: { $max: `$${String(field)}` }
|
|
763
|
+
};
|
|
764
|
+
if (!isDate) {
|
|
765
|
+
groupFields.avg = { $avg: `$${String(field)}` };
|
|
766
|
+
groupFields.sum = { $sum: `$${String(field)}` };
|
|
767
|
+
}
|
|
776
768
|
|
|
777
|
-
|
|
778
|
-
}
|
|
769
|
+
const aggregations: object[] = [{ $match: queryObject }, { $group: groupFields }];
|
|
779
770
|
|
|
780
|
-
|
|
781
|
-
await QueryVerifier.verify(cls, query);
|
|
771
|
+
const result = await collection.aggregate<NumberFieldAggregateResult>(aggregations).toArray();
|
|
782
772
|
|
|
783
|
-
const
|
|
784
|
-
|
|
785
|
-
return col.countDocuments(filter);
|
|
773
|
+
const row = result.length ? result[0] : { count: 0 };
|
|
774
|
+
return ModelQueryAggregateUtil.resolveAggregate(cls, field, row);
|
|
786
775
|
}
|
|
787
776
|
|
|
788
777
|
// Suggest
|