猫鼬:以没有任何ObjectId的猫鼬填充

猫鼬:以没有任何ObjectId的猫鼬填充

问题描述:

我有2个显示的模式

const gameSchema = new mongoose.Schema({
    title: String,
    rating: { type: Number, min: 0, max: 100 },
    genres: { type: Array, ref: 'Genres' }
})
const GenreSchema = new mongoose.Schema({
    id: { type: Number },
    name: String,
    description: String
})
mongoose.model('Games', gameSchema)
mongoose.model('Genres', GenreSchema)

现在,一个端点/api/games返回游戏的结果数组,其中genres属性包含ID数组,例如. "genres": [4, 7, 19]

Now one endpoint /api/games returns an array of results from games where genres property contains array of id eg. "genres": [4, 7, 19]

如何在没有任何ObjectId的情况下填充genres?我已经尝试过使用普通的ref方法,但是它说

How do I populate genres without any ObjectId? I've tried with normal ref method but it says

{"stringValue":"\"4\"","kind":"ObjectId","value":4,"path":"_id","reason":{},"message":"Cast to ObjectId failed for value \"4\" at path \"_id\" for model \"Genres\"","name":"CastError"}

我想将其指向id而不是_id

您可以使用Virtuals的概念.这是怎么回事:

You can use the concept of Virtuals. Here how it goes:

如下修改您的架构文件:

Modify your schema file as following:

//---------------------------------------------------
const gameSchema = new mongoose.Schema({
  title: String,
  rating: { type: Number, min: 0, max: 100 },
  genres: [Number],//here you have an array of id of type Number as yours, no ref
});
const GenreSchema = new mongoose.Schema({
  id: { type: Number },
  name: String,
  description: String,
});

gameSchema.virtual("games", {
  ref: "Genres",//this is the model to populate
  localField: "id",//the field used to make the populate, it is the field that must match on the aimed  Genres model <- here is the trick you want!!!  
  foreignField: "genres",//the field to populate on Games model
  justOne: false,
});

 gameSchema.set("toObject", { virtuals: true });//if you are planning to use say console.log
 gameSchema.set("toJSON", { virtuals: true });//if you are planning to use say res.json

mongoose.model("Games", gameSchema);
mongoose.model("Genres", GenreSchema);
//-------------------------------------------------

在您要填充的文件上,将其放在声明部分:

On the file you are trying to populate, put this in the declaration section:

//-----------------------------------------------------
const Games = mongoose.model("Games", gameSchema);
//---------------------------------------------------

最后但并非最不重要的一点,您要填充的位置:

Last but not least, where you want to populate:

//----------------------------------------------
Games.find({})
  .populate("games")
  .exec(function (error, games) {
   //with games you can use things like game.field1, it is actually an JSON object! Print out games and see the fieds for your self, select one and call it using the dot notation! 
    console.log(games);
  });
//---------------------------------------------

我已经针对已解决的问题测试了该解决方案,请对其进行修改以满足您的需求,请告诉我它是否可以解决您的问题;如果没有,我们可以一起弄清楚如何使我的解决方案适合您的需求.

I have tested this solution on a problem I had done, just modified to fit your needs, please, let me know if it works in yours; if not, we can figure it out together how to fit my solution to meet your needs.

一些初始参考

  1. 用以下方法填充猫鼬模型不是ID的字段