@travetto/model-mongo 8.0.3 → 8.0.4
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 +47 -48
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#L43)
|
|
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.4",
|
|
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.4",
|
|
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,
|
|
@@ -86,6 +84,7 @@ import {
|
|
|
86
84
|
ShutdownManager,
|
|
87
85
|
TypedObject
|
|
88
86
|
} from '@travetto/runtime';
|
|
87
|
+
import { SchemaRegistryIndex } from '@travetto/schema';
|
|
89
88
|
|
|
90
89
|
import type { MongoModelConfig } from './config.ts';
|
|
91
90
|
import { MongoUtil, type WithId } from './internal/util.ts';
|
|
@@ -641,11 +640,19 @@ export class MongoModelService
|
|
|
641
640
|
return await Promise.all(items.map(item => this.postLoad(cls, item)));
|
|
642
641
|
}
|
|
643
642
|
|
|
644
|
-
async
|
|
643
|
+
async getByQuery<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>, failOnMany = true): Promise<T> {
|
|
645
644
|
const results = await this.query<T>(cls, { ...query, limit: failOnMany ? 2 : 1 });
|
|
646
645
|
return ModelQueryUtil.verifyGetSingleCounts<T>(cls, failOnMany, results, query.where);
|
|
647
646
|
}
|
|
648
647
|
|
|
648
|
+
async countByQuery<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>): Promise<number> {
|
|
649
|
+
await QueryVerifier.verify(cls, query);
|
|
650
|
+
|
|
651
|
+
const col = await this.getStore(cls);
|
|
652
|
+
const filter = MongoUtil.extractWhereFilter(cls, query.where);
|
|
653
|
+
return col.countDocuments(filter);
|
|
654
|
+
}
|
|
655
|
+
|
|
649
656
|
// Query Crud
|
|
650
657
|
async updateByQuery<T extends ModelType>(cls: Class<T>, data: T, query: ModelQuery<T>): Promise<T> {
|
|
651
658
|
await QueryVerifier.verify(cls, query);
|
|
@@ -730,59 +737,51 @@ export class MongoModelService
|
|
|
730
737
|
.toSorted((a, b) => b.count - a.count);
|
|
731
738
|
}
|
|
732
739
|
|
|
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
740
|
// Aggregate
|
|
741
|
-
async aggregateFieldByQuery<
|
|
742
|
-
T
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
await QueryVerifier.verify(
|
|
741
|
+
async aggregateFieldByQuery<T extends ModelType, F extends ValidComparableFields<T>>(
|
|
742
|
+
cls: Class<T>,
|
|
743
|
+
field: F,
|
|
744
|
+
query?: ModelQuery<T>
|
|
745
|
+
): Promise<FieldAggregateResult<T, F>> {
|
|
746
|
+
await QueryVerifier.verify(cls, query);
|
|
747
747
|
|
|
748
|
-
const collection = await this.getStore(
|
|
748
|
+
const collection = await this.getStore(cls);
|
|
749
749
|
|
|
750
|
-
const where = ModelQueryUtil.getWhereClause(
|
|
750
|
+
const where = ModelQueryUtil.getWhereClause(cls, query?.where);
|
|
751
751
|
let queryObject: Record<string, unknown> = { [field]: { $exists: true, $ne: null } };
|
|
752
752
|
|
|
753
753
|
if (where) {
|
|
754
|
-
queryObject = { $and: [queryObject, MongoUtil.extractWhereFilter(
|
|
754
|
+
queryObject = { $and: [queryObject, MongoUtil.extractWhereFilter(cls, where)] };
|
|
755
755
|
}
|
|
756
756
|
|
|
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
|
-
];
|
|
773
|
-
|
|
774
|
-
const result = await collection.aggregate<{ _id: null; value: unknown }>(aggregations).toArray();
|
|
775
|
-
const rawValue = result.length ? result[0].value : undefined;
|
|
776
|
-
|
|
777
|
-
return ModelQueryAggregateUtil.resolveResult(modelClass, operation, field, rawValue);
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
async countByQuery<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>): Promise<number> {
|
|
781
|
-
await QueryVerifier.verify(cls, query);
|
|
757
|
+
const isDate = SchemaRegistryIndex.getNestedFieldConfig(cls, field)!.type === Date;
|
|
782
758
|
|
|
783
|
-
const
|
|
784
|
-
|
|
785
|
-
|
|
759
|
+
const groupFields: Record<string, unknown> = {
|
|
760
|
+
_id: null,
|
|
761
|
+
count: { $sum: 1 },
|
|
762
|
+
min: { $min: `$${String(field)}` },
|
|
763
|
+
max: { $max: `$${String(field)}` }
|
|
764
|
+
};
|
|
765
|
+
if (!isDate) {
|
|
766
|
+
groupFields.avg = { $avg: `$${String(field)}` };
|
|
767
|
+
groupFields.sum = { $sum: `$${String(field)}` };
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
const aggregations: object[] = [{ $match: queryObject }, { $group: groupFields }];
|
|
771
|
+
|
|
772
|
+
const result = await collection
|
|
773
|
+
.aggregate<{
|
|
774
|
+
_id: null;
|
|
775
|
+
count?: number;
|
|
776
|
+
min?: unknown;
|
|
777
|
+
max?: unknown;
|
|
778
|
+
avg?: unknown;
|
|
779
|
+
sum?: unknown;
|
|
780
|
+
}>(aggregations)
|
|
781
|
+
.toArray();
|
|
782
|
+
|
|
783
|
+
const row = result.length ? result[0] : { count: 0 };
|
|
784
|
+
return ModelQueryAggregateUtil.resolveAggregate(cls, field, row);
|
|
786
785
|
}
|
|
787
786
|
|
|
788
787
|
// Suggest
|