From 57ba3ed50f26ec15a3867b77d011332c7babafc8 Mon Sep 17 00:00:00 2001 From: Ali Ghorbani Date: Thu, 19 Sep 2024 17:56:13 +0330 Subject: [PATCH 1/2] fix #3057 --- packages/mongodb/src/adapter.ts | 40 +++++++++++++++++---------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/packages/mongodb/src/adapter.ts b/packages/mongodb/src/adapter.ts index b640bf395d..67fc232b8d 100644 --- a/packages/mongodb/src/adapter.ts +++ b/packages/mongodb/src/adapter.ts @@ -129,17 +129,30 @@ export class MongoDbAdapter< } /* TODO: Remove $out and $merge stages, else it returns an empty cursor. I think its safe to assume this is primarily for querying. */ - async aggregateRaw(params: ServiceParams) { - const model = await this.getModel(params) + parsePipeline(params: ServiceParams) { const pipeline = params.pipeline || [] const index = pipeline.findIndex((stage: Document) => stage.$feathers) const before = index >= 0 ? pipeline.slice(0, index) : [] - const feathersPipeline = this.makeFeathersPipeline(params) const after = index >= 0 ? pipeline.slice(index + 1) : pipeline + return { before, after } + } + + async aggregateRaw(params: ServiceParams) { + const model = await this.getModel(params) + const { before, after } = this.parsePipeline(params) + const feathersPipeline = this.makeFeathersPipeline(params) return model.aggregate([...before, ...feathersPipeline, ...after], params.mongodb) } + async countAggregate(params: ServiceParams) { + const model = await this.getModel(params) + const { before, after } = this.parsePipeline(params) + + const res = await model.aggregate([...before, ...after, { $count: 'total' }], params.mongodb).then((result) => result.toArray()) + return res?.pop()?.totla ?? 0 + } + makeFeathersPipeline(params: ServiceParams) { const { filters, query } = this.filterQuery(null, params) const pipeline: Document[] = [{ $match: query }] @@ -210,21 +223,6 @@ export class MongoDbAdapter< const { useEstimatedDocumentCount } = this.getOptions(params) const { query } = this.filterQuery(null, params) - if (params.pipeline) { - const aggregateParams = { - ...params, - query: { - ...params.query, - $select: [this.id], - $sort: undefined, - $skip: undefined, - $limit: undefined - } - } - const result = await this.aggregateRaw(aggregateParams).then((result) => result.toArray()) - return result.length - } - const model = await this.getModel(params) if (useEstimatedDocumentCount && typeof model.estimatedDocumentCount === 'function') { @@ -294,6 +292,10 @@ export class MongoDbAdapter< return result.then((result) => result.toArray()) } + const getTotal = () => { + return params.pipeline ? this.countAggregate(params) : this.countDocuments(params) + } + if (paginationDisabled) { if (filters.$limit === 0) { return [] as Result[] @@ -311,7 +313,7 @@ export class MongoDbAdapter< } } - const [data, total] = await Promise.all([getData(), this.countDocuments(params)]) + const [data, total] = await Promise.all([getData(), getTotal()]) return { total, From 231a7a278791c9b822a08a71dfa6c62bb3e7151d Mon Sep 17 00:00:00 2001 From: Ali Ghorbani Date: Sat, 5 Oct 2024 14:58:02 +0330 Subject: [PATCH 2/2] replace promise with direct call to toArray method --- packages/mongodb/src/adapter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mongodb/src/adapter.ts b/packages/mongodb/src/adapter.ts index 67fc232b8d..e13daad3f3 100644 --- a/packages/mongodb/src/adapter.ts +++ b/packages/mongodb/src/adapter.ts @@ -149,7 +149,7 @@ export class MongoDbAdapter< const model = await this.getModel(params) const { before, after } = this.parsePipeline(params) - const res = await model.aggregate([...before, ...after, { $count: 'total' }], params.mongodb).then((result) => result.toArray()) + const res = await model.aggregate([...before, ...after, { $count: 'total' }], params.mongodb).toArray() return res?.pop()?.totla ?? 0 }