* @inheritDoc
(
entityName: EntityName<Entity>,
groupBy: EntityKey<Entity> | readonly EntityKey<Entity>[],
options: CountByOptions<Entity> = {},
)
| 67 | * @inheritDoc |
| 68 | */ |
| 69 | override async countBy<Entity extends object>( |
| 70 | entityName: EntityName<Entity>, |
| 71 | groupBy: EntityKey<Entity> | readonly EntityKey<Entity>[], |
| 72 | options: CountByOptions<Entity> = {}, |
| 73 | ): Promise<Dictionary<number>> { |
| 74 | const em = this.getContext(false) as MongoEntityManager; |
| 75 | options = { ...options }; |
| 76 | em.prepareOptions(options); |
| 77 | const meta = em.getMetadata().find(entityName)!; |
| 78 | const fields = Utils.asArray(groupBy); |
| 79 | |
| 80 | if (options.having) { |
| 81 | throw new Error('The `having` option is not supported for MongoDB in `countBy`.'); |
| 82 | } |
| 83 | |
| 84 | await em.tryFlush(entityName, options); |
| 85 | const rawWhere = options.where; |
| 86 | const where = await em.processWhere(entityName, rawWhere ?? ({} as FilterQuery<Entity>), options as any, 'read'); |
| 87 | const renamedWhere = em.getDriver().renameFields(meta.class, where as Entity, true); |
| 88 | |
| 89 | const fieldNames = fields.map(f => meta.properties[f as EntityKey<Entity>]?.fieldNames?.[0] ?? f); |
| 90 | const groupId = |
| 91 | fieldNames.length === 1 ? `$${fieldNames[0]}` : Object.fromEntries(fieldNames.map(f => [f, `$${f}`])); |
| 92 | |
| 93 | const pipeline: Dictionary[] = []; |
| 94 | |
| 95 | if (renamedWhere && Object.keys(renamedWhere).length > 0) { |
| 96 | pipeline.push({ $match: renamedWhere }); |
| 97 | } |
| 98 | |
| 99 | pipeline.push({ $group: { _id: groupId, count: { $sum: 1 } } }); |
| 100 | |
| 101 | const rows = await em.getDriver().aggregate(meta.class, pipeline, em.getTransactionContext(), em.signal); |
| 102 | const results: Dictionary<number> = {}; |
| 103 | |
| 104 | for (const row of rows) { |
| 105 | const key = |
| 106 | fieldNames.length === 1 ? String(row._id) : fieldNames.map(f => String(row._id[f])).join(Utils.PK_SEPARATOR); |
| 107 | results[key] = +row.count; |
| 108 | } |
| 109 | |
| 110 | return results; |
| 111 | } |
| 112 | |
| 113 | /** |
| 114 | * @inheritDoc |
nothing calls this directly
no test coverage detected