Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/bulk/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ export class FindOperators {
}

/** Add a multiple update operation to the bulk operation */
update(updateDocument: Document): BulkOperationBase {
update(updateDocument: Document | Document[]): BulkOperationBase {
const currentOp = buildCurrentOp(this.bulkOperation);
return this.bulkOperation.addToOperationsList(
BatchType.UPDATE,
Expand All @@ -796,7 +796,7 @@ export class FindOperators {
}

/** Add a single update operation to the bulk operation */
updateOne(updateDocument: Document): BulkOperationBase {
updateOne(updateDocument: Document | Document[]): BulkOperationBase {
if (!hasAtomicOperators(updateDocument)) {
throw new MongoInvalidArgumentError('Update document requires atomic operators');
}
Expand Down Expand Up @@ -868,6 +868,16 @@ export class FindOperators {
this.bulkOperation.s.currentOp.arrayFilters = arrayFilters;
return this;
}

/** Specifies hint for the bulk operation. */
hint(hint: Hint): this {
if (!this.bulkOperation.s.currentOp) {
this.bulkOperation.s.currentOp = {};
}

this.bulkOperation.s.currentOp.hint = hint;
return this;
}
}

/** @internal */
Expand Down
4 changes: 2 additions & 2 deletions src/operations/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export interface UpdateOptions extends CommandOperationOptions {
/** Specifies a collation */
collation?: CollationOptions;
/** Specify that the update query should only consider plans using the hinted index */
hint?: string | Document;
hint?: Hint;
/** When true, creates a new document if no document matches the query */
upsert?: boolean;
/** Map of parameter names and values that can be accessed using $$var (requires MongoDB 5.0). */
Expand Down Expand Up @@ -280,7 +280,7 @@ export class ReplaceOneOperation extends UpdateOperation {

export function makeUpdateStatement(
filter: Document,
update: Document,
update: Document | Document[],
options: UpdateOptions & { multi?: boolean }
): UpdateStatement {
if (filter == null || typeof filter !== 'object') {
Expand Down
63 changes: 63 additions & 0 deletions test/integration/crud/bulk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1688,6 +1688,51 @@ describe('Bulk', function () {
}
});

it('should apply hint via FindOperators', {
metadata: { requires: { mongodb: '>= 4.4' } },
async test() {
const bulk = client.db().collection('coll').initializeOrderedBulkOp();

const events = [];
client.on('commandStarted', event => {
if (['update', 'delete'].includes(event.commandName)) {
events.push(event);
}
});

// updates
bulk
.find({ b: 1 })
.hint({ b: 1 })
.updateOne({ $set: { b: 2 } });
bulk
.find({ b: 2 })
.hint({ b: 1 })
.update({ $set: { b: 3 } });
bulk.find({ b: 3 }).hint({ b: 1 }).replaceOne({ b: 2 });

// deletes
bulk.find({ b: 2 }).hint({ b: 1 }).deleteOne();
bulk.find({ b: 1 }).hint({ b: 1 }).delete();

await bulk.execute();

expect(events).to.be.an('array').with.length.at.least(1);
expect(events[0]).property('commandName').to.equal('update');
const updateCommand = events[0].command;
expect(updateCommand).property('updates').to.be.an('array').with.length(3);
updateCommand.updates.forEach(statement => {
expect(statement).property('hint').to.eql({ b: 1 });
});
expect(events[1]).property('commandName').to.equal('delete');
const deleteCommand = events[1].command;
expect(deleteCommand).property('deletes').to.be.an('array').with.length(2);
deleteCommand.deletes.forEach(statement => {
expect(statement).property('hint').to.eql({ b: 1 });
});
}
});

it('should apply arrayFilters to bulk updates via FindOperators', {
metadata: { requires: { mongodb: '>= 3.6' } },
test: function (done) {
Expand Down Expand Up @@ -1737,6 +1782,24 @@ describe('Bulk', function () {
}
});

it('should accept pipeline-style updates', {
metadata: { requires: { mongodb: '>= 4.2' } },
async test() {
const coll = client.db().collection('coll');
const bulk = coll.initializeOrderedBulkOp();

coll.insertMany([{ a: 1 }, { a: 2 }]);

bulk.find({ a: 1 }).updateOne([{ $project: { a: { $add: ['$a', 10] } } }]);
bulk.find({ a: 2 }).update([{ $project: { a: { $add: ['$a', 100] } } }]);

await bulk.execute();

const contents = await coll.find().project({ _id: 0 }).toArray();
expect(contents).to.deep.equal([{ a: 11 }, { a: 102 }]);
}
});

it('should throw an error if raw operations are passed to bulkWrite', function () {
const coll = client.db().collection('single_bulk_write_error');
return coll
Expand Down