Skip to content

Commit 622946d

Browse files
committed
feat: add Mongo bulkWrite API MONGOSH-1100
1 parent bc5cfd6 commit 622946d

File tree

5 files changed

+114
-2
lines changed

5 files changed

+114
-2
lines changed

packages/service-provider-core/src/all-transport-types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ export type {
22
AggregateOptions,
33
AggregationCursor,
44
AnyBulkWriteOperation,
5+
AnyClientBulkWriteModel,
56
Batch,
67
BulkWriteOptions,
78
BulkWriteResult,
9+
ClientBulkWriteResult,
810
ChangeStream,
911
ChangeStreamOptions,
1012
ClientSession,

packages/service-provider-core/src/writable.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { RunCursorCommandOptions } from 'mongodb';
1+
import type { ClientBulkWriteOptions, RunCursorCommandOptions } from 'mongodb';
22
import type {
33
Document,
44
InsertOneOptions,
@@ -10,6 +10,8 @@ import type {
1010
FindOneAndUpdateOptions,
1111
BulkWriteOptions,
1212
AnyBulkWriteOperation,
13+
AnyClientBulkWriteModel,
14+
ClientBulkWriteResult,
1315
DeleteOptions,
1416
DeleteResult,
1517
InsertManyResult,
@@ -108,6 +110,18 @@ export default interface Writable {
108110
dbOptions?: DbOptions
109111
): Promise<BulkWriteResult>;
110112

113+
/**
114+
* Executes a client bulk write operation, available on server 8.0+.
115+
* @param models - The client bulk write models.
116+
* @param options - The bulk write options.
117+
*
118+
* @returns {Promise} The promise of the result.
119+
*/
120+
clientBulkWrite(
121+
models: AnyClientBulkWriteModel<Document>[],
122+
options: ClientBulkWriteOptions
123+
): Promise<ClientBulkWriteResult>;
124+
111125
/**
112126
* Delete multiple documents from the collection.
113127
*

packages/service-provider-node-driver/src/node-driver-service-provider.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ import type {
2323
AggregateOptions,
2424
AggregationCursor,
2525
AnyBulkWriteOperation,
26+
AnyClientBulkWriteModel,
2627
BulkWriteOptions,
2728
BulkWriteResult,
29+
ClientBulkWriteResult,
2830
ClientSessionOptions,
2931
Collection,
3032
CountDocumentsOptions,
@@ -630,6 +632,17 @@ export class NodeDriverServiceProvider
630632
.bulkWrite(requests, options);
631633
}
632634

635+
/**
636+
* Executes a client bulk write operation, available on server 8.0+.
637+
*/
638+
clientBulkWrite(
639+
models: AnyClientBulkWriteModel<Document>[],
640+
options: BulkWriteOptions = {}
641+
): Promise<ClientBulkWriteResult> {
642+
options = { ...this.baseCmdOptions, ...options };
643+
return this.mongoClient.bulkWrite(models, options);
644+
}
645+
633646
/**
634647
* Close the connection.
635648
*
@@ -997,7 +1010,7 @@ export class NodeDriverServiceProvider
9971010
options = { ...this.baseCmdOptions, ...options };
9981011
return this.db(database, dbOptions)
9991012
.collection(collection)
1000-
.replaceOne(filter, replacement, options) as Promise<UpdateResult>;
1013+
.replaceOne(filter, replacement, options);
10011014
// `as UpdateResult` because we know we didn't request .explain() here.
10021015
}
10031016

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,74 @@ describe('Mongo', function () {
10151015
).toArray();
10161016
});
10171017
});
1018+
1019+
context('post-8.0', function () {
1020+
skipIfServerVersion(testServer, '< 8.0');
1021+
let mongo: Mongo;
1022+
1023+
describe('bulkWrite', function () {
1024+
beforeEach(async function () {
1025+
mongo = await instanceState.shellApi.Mongo(uri, undefined, {
1026+
api: { version: '1' },
1027+
});
1028+
});
1029+
1030+
it('should allow inserts across collections and databases', async function () {
1031+
expect(
1032+
await mongo.bulkWrite([
1033+
{
1034+
name: 'insertOne',
1035+
namespace: 'db.authors',
1036+
document: { name: 'King' },
1037+
},
1038+
{
1039+
name: 'deleteOne',
1040+
namespace: 'db.authors',
1041+
filter: { name: 'King' },
1042+
},
1043+
{
1044+
name: 'insertOne',
1045+
namespace: 'db.moreAuthors',
1046+
document: { name: 'Queen' },
1047+
},
1048+
{
1049+
name: 'insertOne',
1050+
namespace: 'otherDb.authors',
1051+
document: { name: 'Prince' },
1052+
},
1053+
])
1054+
).deep.equals({
1055+
acknowledged: true,
1056+
insertedCount: 3,
1057+
upsertedCount: 0,
1058+
matchedCount: 0,
1059+
modifiedCount: 0,
1060+
deletedCount: 1,
1061+
insertResults: undefined,
1062+
updateResults: undefined,
1063+
deleteResults: undefined,
1064+
});
1065+
1066+
expect(
1067+
await mongo.getDB('db').getCollection('authors').count()
1068+
).equals(0);
1069+
1070+
expect(
1071+
await mongo
1072+
.getDB('db')
1073+
.getCollection('moreAuthors')
1074+
.count({ name: 'Queen' })
1075+
).equals(1);
1076+
1077+
expect(
1078+
await mongo
1079+
.getDB('otherDb')
1080+
.getCollection('authors')
1081+
.count({ name: 'Prince' })
1082+
).equals(1);
1083+
});
1084+
});
1085+
});
10181086
});
10191087
});
10201088
});

packages/shell-api/src/mongo.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import type {
3636
ServerApi,
3737
ServerApiVersion,
3838
WriteConcern,
39+
AnyClientBulkWriteModel,
40+
ClientBulkWriteResult,
3941
} from '@mongosh/service-provider-core';
4042
import type { ConnectionInfo } from '@mongosh/arg-parser';
4143
import {
@@ -62,6 +64,7 @@ import { ShellApiErrors } from './error-codes';
6264
import type { LogEntry } from './log-entry';
6365
import { parseAnyLogEntry } from './log-entry';
6466
import type { ShellBson } from './shell-bson';
67+
import type { ClientBulkWriteOptions } from 'mongodb';
6568

6669
/* Utility, inverse of Readonly<T> */
6770
type Mutable<T> = {
@@ -365,6 +368,18 @@ export default class Mongo extends ShellApiClass {
365368
return await this._listDatabases(options);
366369
}
367370

371+
@returnsPromise
372+
@serverVersions(['8.0.0', ServerVersions.latest])
373+
@apiVersions([1])
374+
bulkWrite(
375+
models: AnyClientBulkWriteModel<Document>[],
376+
options: ClientBulkWriteOptions = {}
377+
): Promise<ClientBulkWriteResult> {
378+
this._emitMongoApiCall('bulkWrite', { options });
379+
380+
return this._serviceProvider.clientBulkWrite(models, options);
381+
}
382+
368383
@returnsPromise
369384
@apiVersions([1])
370385
async getDBNames(options: ListDatabasesOptions = {}): Promise<string[]> {

0 commit comments

Comments
 (0)