Skip to content

Commit

Permalink
fix(populate): allow populating paths underneath subdocument maps
Browse files Browse the repository at this point in the history
Fix #9359
  • Loading branch information
vkarpov15 committed Aug 30, 2020
1 parent 63a0a46 commit 743c7f1
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 5 deletions.
9 changes: 7 additions & 2 deletions lib/helpers/populate/assignVals.js
Expand Up @@ -5,6 +5,7 @@ const assignRawDocsToIdStructure = require('./assignRawDocsToIdStructure');
const get = require('../get');
const getVirtual = require('./getVirtual');
const leanPopulateMap = require('./leanPopulateMap');
const lookupLocalFields = require('./lookupLocalFields');
const mpath = require('mpath');
const sift = require('sift').default;
const utils = require('../../utils');
Expand Down Expand Up @@ -68,7 +69,7 @@ module.exports = function assignVals(o) {
}

for (let i = 0; i < docs.length; ++i) {
const existingVal = utils.getValue(o.path, docs[i]);
const existingVal = mpath.get(o.path, docs[i], lookupLocalFields);
if (existingVal == null && !getVirtual(o.originalModel.schema, o.path)) {
continue;
}
Expand Down Expand Up @@ -132,6 +133,10 @@ module.exports = function assignVals(o) {
break;
}

if (parts[j] === '$*') {
break;
}

if (cur[parts[j]] == null) {
// If nothing to set, avoid creating an unnecessary array. Otherwise
// we'll end up with a single doc in the array with only defaults.
Expand All @@ -156,7 +161,7 @@ module.exports = function assignVals(o) {
// If lean, need to check that each individual virtual respects
// `justOne`, because you may have a populated virtual with `justOne`
// underneath an array. See gh-6867
utils.setValue(o.path, valueToSet, docs[i], setValue, false);
mpath.set(o.path, valueToSet, docs[i], lookupLocalFields, setValue, false);
}
};

Expand Down
8 changes: 5 additions & 3 deletions lib/helpers/populate/getModelsMapForPopulate.js
Expand Up @@ -7,6 +7,8 @@ const getDiscriminatorByValue = require('../discriminator/getDiscriminatorByValu
const isPathExcluded = require('../projection/isPathExcluded');
const getSchemaTypes = require('./getSchemaTypes');
const getVirtual = require('./getVirtual');
const lookupLocalFields = require('./lookupLocalFields');
const mpath = require('mpath');
const normalizeRefPath = require('./normalizeRefPath');
const util = require('util');
const utils = require('../../utils');
Expand Down Expand Up @@ -203,16 +205,16 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
options.isVirtual && get(virtual, 'options.getters', false);
if (localFieldGetters.length > 0 && getters) {
const hydratedDoc = (doc.$__ != null) ? doc : model.hydrate(doc);
const localFieldValue = utils.getValue(localField, doc);
const localFieldValue = mpath.get(localField, doc, lookupLocalFields);
if (Array.isArray(localFieldValue)) {
const localFieldHydratedValue = utils.getValue(localField.split('.').slice(0, -1), hydratedDoc);
const localFieldHydratedValue = mpath.get(localField.split('.').slice(0, -1), hydratedDoc, lookupLocalFields);
ret = localFieldValue.map((localFieldArrVal, localFieldArrIndex) =>
localFieldPath.applyGetters(localFieldArrVal, localFieldHydratedValue[localFieldArrIndex]));
} else {
ret = localFieldPath.applyGetters(localFieldValue, hydratedDoc);
}
} else {
ret = convertTo_id(utils.getValue(localField, doc), schema);
ret = convertTo_id(mpath.get(localField, doc, lookupLocalFields), schema);
}

const id = String(utils.getValue(foreignField, doc));
Expand Down
26 changes: 26 additions & 0 deletions lib/helpers/populate/lookupLocalFields.js
@@ -0,0 +1,26 @@
'use strict';

module.exports = function lookupLocalFields(cur, path, val) {
if (cur == null) {
return cur;
}

if (cur._doc != null) {
cur = cur._doc;
}

if (arguments.length >= 3) {
cur[path] = val;
return val;
}


// Support populating paths under maps using `map.$*.subpath`
if (path === '$*') {
return cur instanceof Map ?
Array.from(cur.values()) :
Object.keys(cur).map(key => cur[key]);
}

return cur[path];
};

0 comments on commit 743c7f1

Please sign in to comment.