Skip to content

Commit c65a5b5

Browse files
authored
fix(shell-api): Align database and collection aggregate functions MONGOSH-1868 (#2229)
1 parent 42c83d6 commit c65a5b5

File tree

3 files changed

+58
-25
lines changed

3 files changed

+58
-25
lines changed

packages/shell-api/src/collection.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import type {
6666
UpdateOptions,
6767
DropCollectionOptions,
6868
CheckMetadataConsistencyOptions,
69+
AggregateOptions,
6970
} from '@mongosh/service-provider-core';
7071
import type { RunCommandCursor, Database } from './index';
7172
import {
@@ -159,26 +160,27 @@ export default class Collection extends ShellApiWithMongoClass {
159160
*/
160161
async aggregate(
161162
pipeline: Document[],
162-
options: Document & { explain?: never }
163-
): Promise<AggregationCursor>;
163+
options: AggregateOptions & { explain: ExplainVerbosityLike }
164+
): Promise<Document>;
164165
async aggregate(
165166
pipeline: Document[],
166-
options: Document & { explain: ExplainVerbosityLike }
167-
): Promise<Document>;
167+
options?: AggregateOptions
168+
): Promise<AggregationCursor>;
168169
async aggregate(...stages: Document[]): Promise<AggregationCursor>;
169170
@returnsPromise
170171
@returnType('AggregationCursor')
171172
@apiVersions([1])
172-
async aggregate(...args: any[]): Promise<any> {
173-
let options;
174-
let pipeline;
173+
async aggregate(...args: unknown[]): Promise<AggregationCursor | Document> {
174+
let options: AggregateOptions;
175+
let pipeline: Document[];
175176
if (args.length === 0 || Array.isArray(args[0])) {
176177
options = args[1] || {};
177-
pipeline = args[0] || [];
178+
pipeline = (args[0] as Document[]) || [];
178179
} else {
179180
options = {};
180-
pipeline = args || [];
181+
pipeline = (args as Document[]) || [];
181182
}
183+
182184
if ('background' in options) {
183185
await this._instanceState.printWarning(
184186
aggregateBackgroundOptionNotSupportedHelp

packages/shell-api/src/database.spec.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,12 +401,25 @@ describe('Database', function () {
401401
});
402402

403403
it('supports a single aggregation stage', async function () {
404-
await database.aggregate({ $piplelineStage: {} }, { options: true });
404+
await database.aggregate({ $piplelineStage: {} });
405405

406406
expect(serviceProvider.aggregateDb).to.have.been.calledWith(
407407
database._name,
408408
[{ $piplelineStage: {} }],
409-
{ options: true }
409+
{}
410+
);
411+
});
412+
413+
it('supports passing args as aggregation stages', async function () {
414+
await database.aggregate(
415+
{ $piplelineStage: {} },
416+
{ $piplelineStage2: {} }
417+
);
418+
419+
expect(serviceProvider.aggregateDb).to.have.been.calledWith(
420+
database._name,
421+
[{ $piplelineStage: {} }, { $piplelineStage2: {} }],
422+
{}
410423
);
411424
});
412425

@@ -2891,7 +2904,9 @@ describe('Database', function () {
28912904
it('runs a $sql aggregation', async function () {
28922905
const serviceProviderCursor = stubInterface<ServiceProviderAggCursor>();
28932906
serviceProvider.aggregateDb.returns(serviceProviderCursor as any);
2894-
await database.sql('SELECT * FROM somecollection;', { options: true });
2907+
await database.sql('SELECT * FROM somecollection;', {
2908+
serializeFunctions: true,
2909+
});
28952910
expect(serviceProvider.aggregateDb).to.have.been.calledWith(
28962911
database._name,
28972912
[
@@ -2904,7 +2919,7 @@ describe('Database', function () {
29042919
},
29052920
},
29062921
],
2907-
{ options: true }
2922+
{ serializeFunctions: true }
29082923
);
29092924
});
29102925

packages/shell-api/src/database.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ import type {
5252
CreateEncryptedCollectionOptions,
5353
CheckMetadataConsistencyOptions,
5454
RunCommandOptions,
55+
ExplainVerbosityLike,
56+
AggregateOptions,
5557
} from '@mongosh/service-provider-core';
5658

5759
export type CollectionNamesWithTypes = {
@@ -413,27 +415,38 @@ export default class Database extends ShellApiWithMongoClass {
413415
}
414416

415417
/**
416-
* Run an aggregation against the db.
418+
* Run an aggregation against the database. Accepts array pipeline and options object OR stages as individual arguments.
417419
*
418-
* @param pipeline
419-
* @param options
420420
* @returns {Promise} The promise of aggregation results.
421421
*/
422+
async aggregate(
423+
pipeline: Document[],
424+
options: AggregateOptions & { explain: ExplainVerbosityLike }
425+
): Promise<Document>;
426+
async aggregate(
427+
pipeline: Document[],
428+
options?: AggregateOptions
429+
): Promise<AggregationCursor>;
430+
async aggregate(...stages: Document[]): Promise<AggregationCursor>;
422431
@returnsPromise
423432
@returnType('AggregationCursor')
424433
@apiVersions([1])
425-
async aggregate(
426-
pipelineOrSingleStage: Document | Document[],
427-
options?: Document
428-
): Promise<AggregationCursor> {
429-
if ('background' in (options ?? {})) {
434+
async aggregate(...args: unknown[]): Promise<AggregationCursor | Document> {
435+
let options: AggregateOptions;
436+
let pipeline: Document[];
437+
if (args.length === 0 || Array.isArray(args[0])) {
438+
options = args[1] || {};
439+
pipeline = (args[0] as Document[]) || [];
440+
} else {
441+
options = {};
442+
pipeline = (args as Document[]) || [];
443+
}
444+
445+
if ('background' in options) {
430446
await this._instanceState.printWarning(
431447
aggregateBackgroundOptionNotSupportedHelp
432448
);
433449
}
434-
const pipeline: Document[] = Array.isArray(pipelineOrSingleStage)
435-
? pipelineOrSingleStage
436-
: [pipelineOrSingleStage];
437450

438451
assertArgsDefinedType([pipeline], [true], 'Database.aggregate');
439452

@@ -1731,7 +1744,10 @@ export default class Database extends ShellApiWithMongoClass {
17311744
@serverVersions(['4.4.0', ServerVersions.latest])
17321745
@returnsPromise
17331746
@returnType('AggregationCursor')
1734-
async sql(sqlString: string, options?: Document): Promise<AggregationCursor> {
1747+
async sql(
1748+
sqlString: string,
1749+
options?: AggregateOptions
1750+
): Promise<AggregationCursor> {
17351751
this._emitDatabaseApiCall('sql', { sqlString: sqlString, options });
17361752
await this._instanceState.shellApi.print(
17371753
'Note: this is an experimental feature that may be subject to change in future releases.'

0 commit comments

Comments
 (0)