使用Document.populate()
方法填充字段(放置在数组内)后,生成的文档将返回null,应将子文档放置在该位置。使问题难以解决的原因是,这种行为是意外的,因为它仅在相同集合的某些文档中发生。如您所见,我的模型有点复杂,所以也许我们的问题就是因为这个原因。
主要型号:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const moment = require('moment');
var ActuacioSchema = new Schema({
activa: Boolean,
tancada: Boolean,
ambit: [ { espai: String, idAlias: String, item: { type: Schema.Types.ObjectId, refPath: 'ambit.espai' } } ],
// ... IMPORTANT PART BELOW
persones: [
{
item: { type: Schema.Types.ObjectId, refPath: 'persones.col' },
col: String,
rol: String,
convocat: Boolean,
confirmat: Boolean,
validat: Boolean,
}
],
// ... IMPORTANT PART ABOVE
metadata: {
editors: [ { type: Schema.Types.ObjectId, ref: 'usuaries' } ],
ultimCanvi: {
tmp: { type: Date, default: Date.now},
usu: { type: Schema.Types.ObjectId, ref: 'usuaries' }
},
creacio: {
tmp: { type: Date, default: Date.now},
usu: { type: Schema.Types.ObjectId, ref: 'usuaries' }
}
}
});
module.exports = mongoose.model('actuacions', ActuacioSchema);
如您所见,我有一个要填充的子文档数组,并且我知道基于每个col
字段值的集合。
现在让我们看一下我们子填充的子文档的示例(如您所见,它们都有一个共同的部分,我们需要子填充):
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var MonitoraSchema = new Schema({
idUsuaria: { type: Schema.Types.ObjectId, ref: 'usuaries', required: true }, // <-- Important
idGrup: { type: Schema.Types.ObjectId, ref: 'grups' }, // <-- Important
idEsplai: { type: Schema.Types.ObjectId, ref: 'esplais' }, // <-- Important
admin: { type: Boolean, required: true },
activa: { type: Boolean, required: true },
cursos: [Number],
tasques: [String],
// ...
});
module.exports = mongoose.model('monitores', MonitoraSchema);
在另一个模型中,我们看到需要为之前进行的每个人口子化的字段。就像我说的那样,它们都不是相同的架构(它们来自不同的集合),但是它们具有一些我们需要填充的共同字段,例如idUsuaria
。它们还具有一些特定于我们将要填充的每种模式的字段,并且仅当子文档属于该特定类型时才可以访问,例如idGrup
或idEsplai
。
最后,让我向您展示执行所有这些过程的逻辑控制器:
// newDoc is the base document of Model 'Actuacio', without populating
_.each(newDoc.persones, (u, i) => {
if(!u.dataCache.valid || dm(u.dataCache.expire).isSameOrBefore()) {
// Here we populate some elements of the array based on a condition.
// We populate first the element in the array, and then the subdocument again with those specific fields
newDoc.populate({ path: `persones.${i}.item`, populate: { path: 'idUsuaria idGrup idEsplai idSector idComissio', select: 'desc' } });
}
})
newDoc.execPopulate().then(
function(docPersones) {
_.each(docPersones.persones, (v, j) => {
if(docPersones.populated(`persones.${j}.item`)) {
// IMPORTANT PART: Here we iterate through the array that we populated
v.dataCache.data.nom = v.item.idUsuaria.nomComplet;
if(v.item.idEsplai) v.dataCache.data.esplai = v.item.idEsplai.desc.nom || "";
if(v.item.idGrup) v.dataCache.data.grup = v.item.idGrup.desc.nom || "";
// ....
因此,在最后一部分,我们进行迭代的时间是问题发生的时间。我们检查数组中的每个项目是否被填充以执行某些操作。事实是,对于我们之前指示的项目,它返回true(因此populate()
调用本身可以工作),但是当我们尝试访问person [i] .item(或v.item)时,它只是 null ,或者ObjectID都不是子文档。
我仔细检查了数据库上的引用,它们都是正确的。
关于如何解决此问题的任何想法?