mon goose: заполнить в mon goose, у которого нет ObjectId - PullRequest
1 голос
/ 12 апреля 2020

У меня есть две схемы, как показано

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 содержит массив идентификаторов, например. "genres": [4, 7, 19]

Как мне заполнить genres без ObjectId? Я пытался с нормальным методом ref, но он говорит

{"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

1 Ответ

2 голосов
/ 12 апреля 2020

Вы можете использовать концепцию Virtuals. Вот как это происходит:

Измените файл схемы следующим образом:

//---------------------------------------------------
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);
//-------------------------------------------------

В файле, который вы пытаетесь заполнить, поместите его в раздел объявления:

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

Последнее, но не менее важное, где вы хотите заполнить:

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

Я проверил это решение на проблеме, которую я сделал, только что изменил в соответствии с вашими потребностями, пожалуйста, дайте мне знать, если оно работает в твои; если нет, мы можем вместе выяснить, как подобрать моё решение для ваших нужд.

Некоторые исходные ссылки

  1. Заполните модель mon goose полем, которое не является идентификатором
...