Skip to content

Commit eded423

Browse files
fix _id generation in bulk writes && misc cleanups
1 parent c093a45 commit eded423

File tree

3 files changed

+47
-38
lines changed

3 files changed

+47
-38
lines changed

src/bulk/common.ts

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { promisify } from 'util';
22

3-
import { type BSONSerializeOptions, type Document, ObjectId, resolveBSONOptions } from '../bson';
3+
import { type BSONSerializeOptions, type Document, resolveBSONOptions } from '../bson';
44
import type { Collection } from '../collection';
55
import {
66
type AnyError,
@@ -12,6 +12,7 @@ import {
1212
} from '../error';
1313
import type { Filter, OneOrMore, OptionalId, UpdateFilter, WithoutId } from '../mongo_types';
1414
import type { CollationOptions, CommandOperationOptions } from '../operations/command';
15+
import { maybeAddIdToDocuments } from '../operations/common_functions';
1516
import { DeleteOperation, type DeleteStatement, makeDeleteStatement } from '../operations/delete';
1617
import { executeOperation } from '../operations/execute_operation';
1718
import { InsertOperation } from '../operations/insert';
@@ -917,7 +918,7 @@ export abstract class BulkOperationBase {
917918
* Create a new OrderedBulkOperation or UnorderedBulkOperation instance
918919
* @internal
919920
*/
920-
constructor(collection: Collection, options: BulkWriteOptions, isOrdered: boolean) {
921+
constructor(private collection: Collection, options: BulkWriteOptions, isOrdered: boolean) {
921922
// determine whether bulkOperation is ordered or unordered
922923
this.isOrdered = isOrdered;
923924

@@ -1032,9 +1033,9 @@ export abstract class BulkOperationBase {
10321033
* ```
10331034
*/
10341035
insert(document: Document): BulkOperationBase {
1035-
if (document._id == null && !shouldForceServerObjectId(this)) {
1036-
document._id = new ObjectId();
1037-
}
1036+
maybeAddIdToDocuments(this.collection, document, {
1037+
forceServerObjectId: this.shouldForceServerObjectId()
1038+
});
10381039

10391040
return this.addToOperationsList(BatchType.INSERT, document);
10401041
}
@@ -1093,21 +1094,16 @@ export abstract class BulkOperationBase {
10931094
throw new MongoInvalidArgumentError('Operation must be an object with an operation key');
10941095
}
10951096
if ('insertOne' in op) {
1096-
const forceServerObjectId = shouldForceServerObjectId(this);
1097-
if (op.insertOne && op.insertOne.document == null) {
1098-
// NOTE: provided for legacy support, but this is a malformed operation
1099-
if (forceServerObjectId !== true && (op.insertOne as Document)._id == null) {
1100-
(op.insertOne as Document)._id = new ObjectId();
1101-
}
1102-
1103-
return this.addToOperationsList(BatchType.INSERT, op.insertOne);
1104-
}
1097+
const forceServerObjectId = this.shouldForceServerObjectId();
1098+
const document =
1099+
op.insertOne && op.insertOne.document == null
1100+
? // NOTE: provided for legacy support, but this is a malformed operation
1101+
(op.insertOne as Document)
1102+
: op.insertOne.document;
11051103

1106-
if (forceServerObjectId !== true && op.insertOne.document._id == null) {
1107-
op.insertOne.document._id = new ObjectId();
1108-
}
1104+
maybeAddIdToDocuments(this.collection, document, { forceServerObjectId });
11091105

1110-
return this.addToOperationsList(BatchType.INSERT, op.insertOne.document);
1106+
return this.addToOperationsList(BatchType.INSERT, document);
11111107
}
11121108

11131109
if ('replaceOne' in op || 'updateOne' in op || 'updateMany' in op) {
@@ -1268,6 +1264,18 @@ export abstract class BulkOperationBase {
12681264
batchType: BatchType,
12691265
document: Document | UpdateStatement | DeleteStatement
12701266
): this;
1267+
1268+
private shouldForceServerObjectId(): boolean {
1269+
if (typeof this.s.options.forceServerObjectId === 'boolean') {
1270+
return this.s.options.forceServerObjectId;
1271+
}
1272+
1273+
if (typeof this.s.collection.s.db.options?.forceServerObjectId === 'boolean') {
1274+
return this.s.collection.s.db.options?.forceServerObjectId;
1275+
}
1276+
1277+
return false;
1278+
}
12711279
}
12721280

12731281
Object.defineProperty(BulkOperationBase.prototype, 'length', {
@@ -1277,18 +1285,6 @@ Object.defineProperty(BulkOperationBase.prototype, 'length', {
12771285
}
12781286
});
12791287

1280-
function shouldForceServerObjectId(bulkOperation: BulkOperationBase): boolean {
1281-
if (typeof bulkOperation.s.options.forceServerObjectId === 'boolean') {
1282-
return bulkOperation.s.options.forceServerObjectId;
1283-
}
1284-
1285-
if (typeof bulkOperation.s.collection.s.db.options?.forceServerObjectId === 'boolean') {
1286-
return bulkOperation.s.collection.s.db.options?.forceServerObjectId;
1287-
}
1288-
1289-
return false;
1290-
}
1291-
12921288
function isInsertBatch(batch: Batch): boolean {
12931289
return batch.batchType === BatchType.INSERT;
12941290
}

src/operations/common_functions.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,37 @@ export async function indexInformation(
4343
return info;
4444
}
4545

46-
export function prepareDocs(
46+
export function maybeAddIdToDocuments(
4747
coll: Collection,
4848
docs: Document[],
4949
options: { forceServerObjectId?: boolean }
50-
): Document[] {
50+
): Document[];
51+
export function maybeAddIdToDocuments(
52+
coll: Collection,
53+
docs: Document,
54+
options: { forceServerObjectId?: boolean }
55+
): Document;
56+
export function maybeAddIdToDocuments(
57+
coll: Collection,
58+
docOrDocs: Document[] | Document,
59+
options: { forceServerObjectId?: boolean }
60+
): Document[] | Document {
5161
const forceServerObjectId =
5262
typeof options.forceServerObjectId === 'boolean'
5363
? options.forceServerObjectId
5464
: coll.s.db.options?.forceServerObjectId;
5565

5666
// no need to modify the docs if server sets the ObjectId
5767
if (forceServerObjectId === true) {
58-
return docs;
68+
return docOrDocs;
5969
}
6070

61-
return docs.map(doc => {
71+
const transform = (doc: Document): Document => {
6272
if (doc._id == null) {
6373
doc._id = coll.s.pkFactory.createPk();
6474
}
6575

6676
return doc;
67-
});
77+
};
78+
return Array.isArray(docOrDocs) ? docOrDocs.map(transform) : transform(docOrDocs);
6879
}

src/operations/insert.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type { MongoDBNamespace } from '../utils';
99
import { WriteConcern } from '../write_concern';
1010
import { BulkWriteOperation } from './bulk_write';
1111
import { CommandOperation, type CommandOperationOptions } from './command';
12-
import { prepareDocs } from './common_functions';
12+
import { maybeAddIdToDocuments } from './common_functions';
1313
import { AbstractOperation, Aspect, defineAspects } from './operation';
1414

1515
/** @internal */
@@ -69,7 +69,7 @@ export interface InsertOneResult<TSchema = Document> {
6969

7070
export class InsertOneOperation extends InsertOperation {
7171
constructor(collection: Collection, doc: Document, options: InsertOneOptions) {
72-
super(collection.s.namespace, prepareDocs(collection, [doc], options), options);
72+
super(collection.s.namespace, maybeAddIdToDocuments(collection, [doc], options), options);
7373
}
7474

7575
override async execute(
@@ -131,7 +131,9 @@ export class InsertManyOperation extends AbstractOperation<InsertManyResult> {
131131
const writeConcern = WriteConcern.fromOptions(options);
132132
const bulkWriteOperation = new BulkWriteOperation(
133133
coll,
134-
prepareDocs(coll, this.docs, options).map(document => ({ insertOne: { document } })),
134+
maybeAddIdToDocuments(coll, this.docs, options).map(document => ({
135+
insertOne: { document }
136+
})),
135137
options
136138
);
137139

0 commit comments

Comments
 (0)