Skip to content

Commit 64d1b29

Browse files
authored
Merge pull request #16080 from pnkov/bug-bulkWrite-sort
Fix Model.bulkWrite sorting
2 parents 7666bb8 + e8e7f60 commit 64d1b29

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

lib/model.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3458,7 +3458,7 @@ Model.bulkWrite = async function bulkWrite(ops, options) {
34583458
sort((v1, v2) => v1.index - v2.index).
34593459
map(v => v.error);
34603460

3461-
const validOps = validOpIndexes.sort().map(index => ops[index]);
3461+
const validOps = validOpIndexes.sort((a, b) => a - b).map(index => ops[index]);
34623462

34633463
if (validOps.length === 0) {
34643464
if (options.throwOnValidationError && validationErrors.length) {

test/model.test.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5321,6 +5321,52 @@ describe('Model', function() {
53215321
assert.strictEqual(doc.num, 2);
53225322
});
53235323

5324+
it('bulkWrite should return insertedIds in the same order as the arguments (gh-16079)', async function() {
5325+
const schema = new mongoose.Schema({
5326+
number: Number
5327+
});
5328+
const Model = db.model('gh16079_1', schema);
5329+
await Model.deleteMany({});
5330+
5331+
const ops = new Array(11).fill().map((_, i) => ({ insertOne: { document: { number: i } } }));
5332+
5333+
const result = await Model.bulkWrite(ops, { ordered: false });
5334+
5335+
const docs = await Promise.all(
5336+
Object.values(result.insertedIds).map(id => Model.findById(id))
5337+
);
5338+
5339+
const resultNumbers = docs.map(doc => doc.number);
5340+
const expectedNumbers = ops.map(op => op.insertOne.document.number);
5341+
5342+
assert.deepStrictEqual(resultNumbers, expectedNumbers);
5343+
});
5344+
5345+
it('bulkWrite error index should point to the right argument (gh-16079)', async function() {
5346+
const schema = new mongoose.Schema({
5347+
number: { type: Number, unique: true }
5348+
});
5349+
const Model = db.model('gh16079_2', schema);
5350+
await Model.deleteMany({});
5351+
await Model.syncIndexes();
5352+
5353+
const ops1 = new Array(11).fill().map((_, i) => ({ insertOne: { document: { number: i } } }));
5354+
await Model.bulkWrite(ops1);
5355+
5356+
const ops2 = new Array(21).fill().map((_, i) => ({ insertOne: { document: { number: 20 - i } } }));
5357+
try {
5358+
await Model.bulkWrite(ops2, { ordered: false });
5359+
assert.fail('Should have thrown BulkWriteError');
5360+
} catch (error) {
5361+
assert.ok(error.name === 'MongoBulkWriteError', `Unexpected error name: ${error.name}`);
5362+
5363+
const errorNumbers = error.writeErrors.map(({ err }) => ops2[err.index].insertOne.document.number);
5364+
const expectedNumbers = ops2.slice(-11).map(op => op.insertOne.document.number);
5365+
5366+
assert.deepStrictEqual(errorNumbers, expectedNumbers);
5367+
}
5368+
});
5369+
53245370
it('alias with lean virtual (gh-6069)', async function() {
53255371
const schema = new mongoose.Schema({
53265372
name: {

0 commit comments

Comments
 (0)