这是我的产品型号。
const featureHeaderSchema = new Schema({
header: {
type: String,
required: true,
},
});
const featureSchema = new Schema({
title: {
type: String,
required: true,
},
parentHeader: { type: Schema.Types.ObjectId, ref: "product.featureHeaders" }, // not sure if this is correct
parentFeature: { type: Schema.Types.ObjectId, ref: "product.features" }, // not sure if this is correct
});
const productSchema = new Schema(
{
title: {
type: String,
required: true,
},
thumbnail: String,
description: String,
manufacture: { type: Schema.Types.ObjectId, ref: "user" },
featureHeaders: {
type: [featureHeaderSchema],
},
features: {
type: [featureSchema],
},
},
{ timestamps: true }
);
const productModel = mongoose.model("product", productSchema);
我想通过 id 查找产品并通过 populate 获取parentHeader 的标题和parentFeature 的标题。
我尝试通过产品 ID 获取产品信息并填充到parentHeader 和parentFeature 上,这样我就可以在输出中包含它们的标题。
我尝试了这个查询:
const output = await productModel
.findById(newProduct._id)
.populate("features.parentFeature")
.exec();
但我收到此错误:MissingSchemaError:尚未为模型“product.features”注册架构。
首先,你想要做的事情是不可能用
populate
实现的。这是因为模式声明中的 ref
属性用于引用模型,而不是路径。它用于告诉 mongoose 您要使用哪个模型来执行 $lookup
,并且 mongoose 期望该模型与数据库中的集合相对应。
其次,您在
productSchema
中为 featureHeaders
和 features
数组使用子文档,因此 populate
无论如何都不会为您工作。
幸运的是,您可以解决此问题并让
populate
为您工作。尽管您的命名约定和用例有点令人困惑,但希望这将有助于解释它是如何完成的:
FeatureHeader
和 Feature
需要有自己的集合,而不是子文档,因此您需要为它们创建模型。import mongoose from "mongoose";
const featureHeaderSchema = new mongoose.Schema({
header: {
type: String,
required: true,
}
});
// You need create the FeatureHeader model
const FeatureHeader = mongoose.model("FeatureHeader", featureHeaderSchema);
const featureSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
parentHeader: {
type: mongoose.Schema.Types.ObjectId,
ref: "FeatureHeader" //< Reference the FeatureHeader model
},
parentFeature: {
type: mongoose.Schema.Types.ObjectId,
ref: "Feature" //< You can reference the same model (i.e self)
}
});
// You need create the Feature model
const Feature = mongoose.model("Feature", featureSchema);
const productSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
thumbnail: String,
description: String,
manufacture: {
type: mongoose.Schema.Types.ObjectId,
ref: "User" //< Capitalise the model name
},
featureHeaders: [{
type: mongoose.Schema.Types.ObjectId,
ref: "FeatureHeader", //< Reference the FeatureHeader model
}],
features: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Feature", //< Reference the Feature model
}],
},
{ timestamps: true });
// You need create the Feature model
const Product = mongoose.model("Product", productSchema);
FeatureHeader
和Feature
需要单独保存在自己的集合中,以便参考。const newFeatureOne = await Feature.create({
title: 'Marvel',
});
const newFeatureHeader = await FeatureHeader.create({
header: 'Superhero'
});
const newFeatureTwo = await Feature.create({
title: 'Repulsor Beams',
parentHeader: newFeatureHeader._id,
parentFeature: newFeatureOne._id
});
const newProduct = await Product.create({
title: 'Repulsor Beams',
//...
//...
featureHeaders: [newFeatureHeader._id],
features: [newFeatureTwo._id],
});
populate
将 ObjectId
替换为相应的文档:const id = req.body.id; //< Could be req.params.id or however you get the id
const product = await Product.findById(id)
.populate("featureHeaders")
.populate("features");
注意:根据您的设计以及模型的范围,您可能需要指定
path
和/或 model
选项对象的 populate
属性,如下所示:
const id = req.body.id; //< Could be req.params.id or however you get the id
const product = await Product.findById(id)
.populate({path: "featureHeaders", model: "FeatureHeader"})
.populate({path: "features", model: "Feature"});