Skip to content

Commit

Permalink
fix(populate): handle multiple localFields + foreignFields using `loc…
Browse files Browse the repository at this point in the history
…alField: function() {}` syntax

Fix #5704
  • Loading branch information
vkarpov15 committed Sep 27, 2018
1 parent 0e2d638 commit 53c39fa
Showing 1 changed file with 26 additions and 11 deletions.
37 changes: 26 additions & 11 deletions lib/model.js
Expand Up @@ -3620,8 +3620,18 @@ function populate(model, docs, options, callback) {
}

hasOne = true;
if (mod.foreignField !== '_id' || !match['_id']) {
match[mod.foreignField] = { $in: ids };
if (mod.foreignField.size === 1) {
const foreignField = Array.from(mod.foreignField)[0];
if (foreignField !== '_id' || !match['_id']) {
match[foreignField] = { $in: ids };
}
} else {
match.$or = [];
for (const foreignField of mod.foreignField) {
if (foreignField !== '_id' || !match['_id']) {
match.$or.push({ [foreignField]: { $in: ids } });
}
}
}

const assignmentOpts = {};
Expand Down Expand Up @@ -3653,9 +3663,11 @@ function populate(model, docs, options, callback) {
// field is not selected, automatically select it because mongoose needs it.
// If projection is exclusive and client explicitly unselected the foreign
// field, that's the client's fault.
if (mod.foreignField !== '_id' && query.selectedInclusively() &&
!isPathSelectedInclusive(query._fields, mod.foreignField)) {
query.select(mod.foreignField);
for (const foreignField of mod.foreignField) {
if (foreignField !== '_id' && query.selectedInclusively() &&
!isPathSelectedInclusive(query._fields, foreignField)) {
query.select(foreignField);
}
}

// If we need to sub-populate, call populate recursively
Expand Down Expand Up @@ -3707,8 +3719,11 @@ function populate(model, docs, options, callback) {
// the query result.
for (let i = 0; i < len; i++) {
val = vals[i];
if (val) {
_val = utils.getValue(mod.foreignField, val);
if (val == null) {
continue;
}
for (const foreignField of mod.foreignField) {
_val = utils.getValue(foreignField, val);
if (Array.isArray(_val)) {
const _valLength = _val.length;
for (let j = 0; j < _valLength; ++j) {
Expand Down Expand Up @@ -3767,7 +3782,6 @@ function populate(model, docs, options, callback) {
// If virtual, make sure to not mutate original field
rawIds: mod.isVirtual ? allIds : mod.allIds,
allIds: allIds,
localField: mod.localField,
foreignField: mod.foreignField,
rawDocs: rawDocs,
rawOrder: rawOrder,
Expand Down Expand Up @@ -4060,15 +4074,16 @@ function getModelsMapForPopulate(model, docs, options) {
docs: [doc],
ids: [ids],
allIds: [ret],
// Assume only 1 localField + foreignField
localField: localField,
foreignField: foreignField,
localField: new Set([localField]),
foreignField: new Set([foreignField]),
justOne: justOne,
isVirtual: isVirtual,
virtual: virtual
};
map.push(available[modelName]);
} else {
available[modelName].localField.add(localField);
available[modelName].foreignField.add(foreignField);
available[modelName].docs.push(doc);
available[modelName].ids.push(ids);
available[modelName].allIds.push(ret);
Expand Down

0 comments on commit 53c39fa

Please sign in to comment.