这是我的产品模型.

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的标题.

我try 通过产品ID获取产品信息,并填充到parentHeader和parentFeature上,这样我就可以在输出中显示它们的标题.

我try 了这个查询:

const output = await productModel
    .findById(newProduct._id)
    .populate("features.parentFeature")
    .exec();

但我得到这个错误:MissingSchemaError: Schema hasn't been registered for model "product.features".

推荐答案

首先,你想做的事情在populate美元是不可能实现的.这是因为模式声明中的ref属性用于引用模型,而不是路径.它用于告诉Mongoose您要使用哪个模型来执行$lookup,Mongoose希望该模型与您的数据库中的集合相对应.

其次,您在featureHeadersfeatures数组中使用的是productSchema中的子文档,因此populate无论如何都不适用于您.

谢天谢地,你可以解决这个问题,并得到populate为你工作.尽管您的命名约定和用例有点令人困惑,但希望这将有助于解释它是如何实现的:

  1. FeatureHeaderFeature需要有自己的集合,而不是子文档,因此需要为它们创建模型.
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);
  1. FeatureHeaderFeature需要分别保存在它们自己的集合中才能被引用.
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],
});
  1. 现在,您可以拨打populateObjectId替换为其相应的文档:
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");

Note:根据您的设计和模型的作用域,您可能需要指定populate Options对象的path和/或model属性,如下所示:

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"});

希望所有这些都是有意义的,如果你有任何问题,请在 comments 中提问.

Javascript相关问答推荐

Vue v模型检测父参考更改

将下拉分区与工具提示结合起来

JavaScript:循环访问不断变化的数组中的元素

我的YouTube视频没有以html形式显示,以获取免费加密信号

如何避免使用ajax在Vue 3合成API中重定向

RxJS setTimeout操作符等效

无法在nextjs应用程序中通过id从mongoDB删除'

使用javascript将Plotly Expandable Sparkline转换为HighCharter Plot在bslib卡中

react—router v6:路由没有路径

单击ImageListItemBar的IconButton后,在Material—UI对话框中显示图像

为什么Mutations 观察器用微任务队列而不是macrotask队列处理?

在Three JS中看不到补间不透明度更改效果

JSDoc创建并从另一个文件导入类型

如何在ASP.NET中使用Google Charts API JavaScript将条形图标签显示为绝对值而不是负值

在Java中寻找三次Bezier曲线上的点及其Angular

以Angular 实现ng-Circle-Progress时出错:模块没有导出的成员

为什么JPG图像不能在VITE中导入以进行react ?

Rxjs流中生成IMMER不能在对象上操作

当标题被点击时,如何使内容出现在另一个div上?

React Refs不与高阶组件(HOC)中的动态生成组件一起工作