【发布时间】:2018-03-04 13:55:52
【问题描述】:
设置
假设我们有Foo 和Bar 的模式。 Foo 有一个字段 bar。此字段可以包含引用文档 Bar 的 ObjectId,也可以包含不是 ObjectId 的其他任意对象。
const fooSchema = new mongoose.Schema({
bar: {
type: mongoose.Schema.Types.Mixed,
ref: 'Bar'
}
});
const Foo = <any>mongoose.model<any>('Foo', fooSchema);
const barSchema = new mongoose.Schema({
name: String
});
const Bar = <any>mongoose.model<any>('Bar', barSchema);
问题
现在假设我们有一堆 Foo 文档。
我希望能够在 bar 字段上使用 mongoose 的 populate 自动将对 Bar 文档的引用替换为实际的 Bar 文档本身。我还想保留所有其他不引用 Bar 文档的对象不变。
通常,我会使用类似的方法来获取所有 Foo 文档,然后填充 bar 字段:
Foo.find().populate('bar')
但是,此方法会在遇到 bar 字段中不是 ObjectId 的对象时抛出异常,而不是让它们保持原样。
UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝 id:1):CastError:转换为 ObjectId 失败,因为模型“Bar”的路径“_id”处的值“一些任意对象”
尝试寻找解决方案
我已经检查了在populate 上使用match 选项,要求Bar 上存在一个字段:
Foo.find().populate({
path: 'bar',
match: {
name: {
$exists: true
}
}
}
不幸的是,错误是一样的。
问题
那么我的问题是,如果字段包含 ObjectId,是否有任何方法可以让猫鼬只使用 populate 字段,否则不理会它?
【问题讨论】:
-
你可以在 find 上添加一个 post hook?,在那里你可以检查 prop 是 ObjectId 还是其他东西,如果它是 ObjectId,你搜索它并将其附加到对象,如果不是,您可以直接调用 next() 而不做任何更改。
-
@SebastiánEspinosa 这听起来可行。但是,不利的一面是,每次我调用
Foo.find()时,它都会自动填充,即使我不调用populate()。因此,在不需要时,我将无法“选择退出”填充。如果我理解正确? -
你添加一个静态方法而不是一个钩子
标签: javascript node.js typescript mongoose mongoose-populate