Skip to content

Commit 16d2407

Browse files
authored
Merge pull request #15238 from Automattic/revert-15231-vkarpov15/gh-15210
Revert "Introduce populate ordered option for populating in series rather than in parallel"
2 parents 9d68b0a + 1668bbb commit 16d2407

File tree

5 files changed

+11
-85
lines changed

5 files changed

+11
-85
lines changed

lib/document.js

-3
Original file line numberDiff line numberDiff line change
@@ -4509,8 +4509,6 @@ Document.prototype.equals = function(doc) {
45094509
* @param {Object|Function} [options.match=null] Add an additional filter to the populate query. Can be a filter object containing [MongoDB query syntax](https://www.mongodb.com/docs/manual/tutorial/query-documents/), or a function that returns a filter object.
45104510
* @param {Function} [options.transform=null] Function that Mongoose will call on every populated document that allows you to transform the populated document.
45114511
* @param {Object} [options.options=null] Additional options like `limit` and `lean`.
4512-
* @param {Boolean} [options.forceRepopulate=true] Set to `false` to prevent Mongoose from repopulating paths that are already populated
4513-
* @param {Boolean} [options.ordered=false] Set to `true` to execute any populate queries one at a time, as opposed to in parallel. We recommend setting this option to `true` if using transactions, especially if also populating multiple paths or paths with multiple models. MongoDB server does **not** support multiple operations in parallel on a single transaction.
45144512
* @param {Function} [callback] Callback
45154513
* @see population https://mongoosejs.com/docs/populate.html
45164514
* @see Query#select https://mongoosejs.com/docs/api/query.html#Query.prototype.select()
@@ -4537,7 +4535,6 @@ Document.prototype.populate = async function populate() {
45374535
}
45384536

45394537
const paths = utils.object.vals(pop);
4540-
45414538
let topLevelModel = this.constructor;
45424539
if (this.$__isNested) {
45434540
topLevelModel = this.$__[scopeSymbol].constructor;

lib/model.js

+8-29
Original file line numberDiff line numberDiff line change
@@ -4369,7 +4369,6 @@ Model.validate = async function validate(obj, pathsOrOptions, context) {
43694369
* @param {Object} [options.options=null] Additional options like `limit` and `lean`.
43704370
* @param {Function} [options.transform=null] Function that Mongoose will call on every populated document that allows you to transform the populated document.
43714371
* @param {Boolean} [options.forceRepopulate=true] Set to `false` to prevent Mongoose from repopulating paths that are already populated
4372-
* @param {Boolean} [options.ordered=false] Set to `true` to execute any populate queries one at a time, as opposed to in parallel. Set this option to `true` if populating multiple paths or paths with multiple models in transactions.
43734372
* @return {Promise}
43744373
* @api public
43754374
*/
@@ -4387,21 +4386,11 @@ Model.populate = async function populate(docs, paths) {
43874386
}
43884387

43894388
// each path has its own query options and must be executed separately
4390-
if (paths.find(p => p.ordered)) {
4391-
// Populate in series, primarily for transactions because MongoDB doesn't support multiple operations on
4392-
// one transaction in parallel.
4393-
// Note that if _any_ path has `ordered`, we make the top-level populate `ordered` as well.
4394-
for (const path of paths) {
4395-
await _populatePath(this, docs, path);
4396-
}
4397-
} else {
4398-
// By default, populate in parallel
4399-
const promises = [];
4400-
for (const path of paths) {
4401-
promises.push(_populatePath(this, docs, path));
4402-
}
4403-
await Promise.all(promises);
4389+
const promises = [];
4390+
for (const path of paths) {
4391+
promises.push(_populatePath(this, docs, path));
44044392
}
4393+
await Promise.all(promises);
44054394

44064395
return docs;
44074396
};
@@ -4521,22 +4510,12 @@ async function _populatePath(model, docs, populateOptions) {
45214510
return;
45224511
}
45234512

4524-
if (populateOptions.ordered) {
4525-
// Populate in series, primarily for transactions because MongoDB doesn't support multiple operations on
4526-
// one transaction in parallel.
4527-
for (const arr of params) {
4528-
await _execPopulateQuery.apply(null, arr).then(valsFromDb => { vals = vals.concat(valsFromDb); });
4529-
}
4530-
} else {
4531-
// By default, populate in parallel
4532-
const promises = [];
4533-
for (const arr of params) {
4534-
promises.push(_execPopulateQuery.apply(null, arr).then(valsFromDb => { vals = vals.concat(valsFromDb); }));
4535-
}
4536-
4537-
await Promise.all(promises);
4513+
const promises = [];
4514+
for (const arr of params) {
4515+
promises.push(_execPopulateQuery.apply(null, arr).then(valsFromDb => { vals = vals.concat(valsFromDb); }));
45384516
}
45394517

4518+
await Promise.all(promises);
45404519

45414520
for (const arr of params) {
45424521
const mod = arr[0];

lib/utils.js

+3-7
Original file line numberDiff line numberDiff line change
@@ -551,8 +551,8 @@ exports.populate = function populate(path, select, model, match, options, subPop
551551
};
552552
}
553553

554-
if (typeof obj.path !== 'string' && !(Array.isArray(obj.path) && obj.path.every(el => typeof el === 'string'))) {
555-
throw new TypeError('utils.populate: invalid path. Expected string or array of strings. Got typeof `' + typeof path + '`');
554+
if (typeof obj.path !== 'string') {
555+
throw new TypeError('utils.populate: invalid path. Expected string. Got typeof `' + typeof path + '`');
556556
}
557557

558558
return _populateObj(obj);
@@ -600,11 +600,7 @@ function _populateObj(obj) {
600600
}
601601

602602
const ret = [];
603-
const paths = oneSpaceRE.test(obj.path)
604-
? obj.path.split(manySpaceRE)
605-
: Array.isArray(obj.path)
606-
? obj.path
607-
: [obj.path];
603+
const paths = oneSpaceRE.test(obj.path) ? obj.path.split(manySpaceRE) : [obj.path];
608604
if (obj.options != null) {
609605
obj.options = clone(obj.options);
610606
}

test/document.populate.test.js

-40
Original file line numberDiff line numberDiff line change
@@ -1075,44 +1075,4 @@ describe('document.populate', function() {
10751075
assert.deepStrictEqual(codeUser.extras[0].config.paymentConfiguration.paymentMethods[0]._id, code._id);
10761076
assert.strictEqual(codeUser.extras[0].config.paymentConfiguration.paymentMethods[0].code, 'test code');
10771077
});
1078-
1079-
it('supports populate with ordered option (gh-15231)', async function() {
1080-
const docSchema = new Schema({
1081-
refA: { type: Schema.Types.ObjectId, ref: 'Test1' },
1082-
refB: { type: Schema.Types.ObjectId, ref: 'Test2' },
1083-
refC: { type: Schema.Types.ObjectId, ref: 'Test3' }
1084-
});
1085-
1086-
const doc1Schema = new Schema({ name: String });
1087-
const doc2Schema = new Schema({ title: String });
1088-
const doc3Schema = new Schema({ content: String });
1089-
1090-
const Doc = db.model('Test', docSchema);
1091-
const Doc1 = db.model('Test1', doc1Schema);
1092-
const Doc2 = db.model('Test2', doc2Schema);
1093-
const Doc3 = db.model('Test3', doc3Schema);
1094-
1095-
const doc1 = await Doc1.create({ name: 'test 1' });
1096-
const doc2 = await Doc2.create({ title: 'test 2' });
1097-
const doc3 = await Doc3.create({ content: 'test 3' });
1098-
1099-
const docD = await Doc.create({
1100-
refA: doc1._id,
1101-
refB: doc2._id,
1102-
refC: doc3._id
1103-
});
1104-
1105-
await docD.populate({
1106-
path: ['refA', 'refB', 'refC'],
1107-
ordered: true
1108-
});
1109-
1110-
assert.ok(docD.populated('refA'));
1111-
assert.ok(docD.populated('refB'));
1112-
assert.ok(docD.populated('refC'));
1113-
1114-
assert.equal(docD.refA.name, 'test 1');
1115-
assert.equal(docD.refB.title, 'test 2');
1116-
assert.equal(docD.refC.content, 'test 3');
1117-
});
11181078
});

types/populate.d.ts

-6
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ declare module 'mongoose' {
3939
foreignField?: string;
4040
/** Set to `false` to prevent Mongoose from repopulating paths that are already populated */
4141
forceRepopulate?: boolean;
42-
/**
43-
* Set to `true` to execute any populate queries one at a time, as opposed to in parallel.
44-
* We recommend setting this option to `true` if using transactions, especially if also populating multiple paths or paths with multiple models.
45-
* MongoDB server does **not** support multiple operations in parallel on a single transaction.
46-
*/
47-
ordered?: boolean;
4842
}
4943

5044
interface PopulateOption {

0 commit comments

Comments
 (0)