В виртуальном населении, как вы определяете ForeignField? - PullRequest
0 голосов
/ 27 марта 2020

Рассмотрим приведенный ниже код:

 require("./connection");

// //----------------------------------------------------
const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const PersonSchema = new Schema({
  name: String,
  band: String,
  father: String
});

const ManagerSchema = new Schema({
  name: String,
  country: String
});

const BandSchema = new Schema({
  name: String
});

BandSchema.virtual("members", {
  ref: "Person", // The model to use
  localField: "name", // Find people where `localField`
  foreignField: "band", // is equal to `foreignField`
  // If `justOne` is true, 'members' will be a single doc as opposed to
  // an array. `justOne` is false by default.
  justOne: false,
  options: { sort: { name: -1 }, limit: 5 } 
});

BandSchema.virtual("managers", {
  ref: "Manager", // The model to use
  localField: "name", // Find people where `localField`
  foreignField: "country", // is equal to `foreignField`
  // If `justOne` is true, 'members' will be a single doc as opposed to
  // an array. `justOne` is false by default.
  justOne: false,
  options: { sort: { name: 1 }, limit: 5 } 
});

//BandSchema.set("toObject", { virtuals: true });
BandSchema.set("toJSON", { virtuals: true });

const Person = mongoose.model("Person", PersonSchema);
const Manager = mongoose.model("Manager", ManagerSchema);

const Band = mongoose.model("Band", BandSchema);

/**
 * Suppose you have 2 bands: "Guns N' Roses" and "Motley Crue"
 * And 4 people: "Axl Rose" and "Slash" with "Guns N' Roses", and
 * "Vince Neil" and "Nikki Sixx" with "Motley Crue"
 */
// Person.create([
//   {
//     name: "Axl Rose",
//     band: "Guns N' Roses"
//   },
//   {
//     name: "Slash",
//     band: "Guns N' Roses"
//   },
//   {
//     name: "Vince Neil",
//     band: "Motley Crue"
//   },
//   {
//     name: "Nikki Sixx",
//     band: "Motley Crue"
//   }
// ]);

// Manager.create([
//   {
//     name: "Bibi",
//     country: "South Africa"
//   },
//   {
//     name: "Storm",
//     country: "Italy"
//   },
//   {
//     name: "Wolverine",
//     country: "Canada"
//   },
//   {
//     name: "Jorge Pires",
//     country: "Brazil"
//   }
// ]);

// Band.create([{ name: "Motley Crue" }, { name: "Guns N' Roses" }]);
/////////////////////////////////////////////////////////////////////////

const app = require("express")();

app.use("/", (req, res) => {
  Band.find({})
    .populate("members")
    .populate("managers")
    .exec(function(error, bands) {
      /* `bands.members` is now an array of instances of `Person` */
      console.log(bands);
      res.json(bands);
    });
});

app.listen(3000, () => {
  console.log("We are on port 3000");
});

/**
 *https://stackoverflow.com/questions/43882577/mongoosejs-virtual-populate
 https://stackoverflow.com/questions/60875380/populate-virtuals-does-not-seem-to-work-could-anyone-show-me-the-error
 */

Рассмотрим соответствующие вопросы:

Мой вопрос: Как вы определяете foreignField?

Members Заполните правильно, но менеджер не .

Я знаю, что проблема в foreignField, потому что, если я повторю всю информацию от участников, она будет правильно заполнена, но теперь у нас есть участники и мы работаем с одним и тем же источником данных.

1 Ответ

0 голосов
/ 13 апреля 2020

После некоторых исследований, пытаясь ответить на другой вопрос здесь о переполнении стека ( mon goose: заполнить в mon goose, у которого нет ObjectId ), я понял, как это работает!

Рассмотрим часть представленного кода:

BandSchema.virtual("members", {
  ref: "Person", // The model to use
  localField: "name", // Find people where `localField`
  foreignField: "band", // this field here has to match the ref path we want to populate!      
  justOne: false,

});

Итак, хитрость заключается в том, чтобы убедиться, что foreignField соответствует полю в модели ref, а localField - это имя поле, которое вы можете найти в заполненной модели: у нас должно быть совпадение между foreignField и localField, точнее: значение localField должно совпадать со значением foreignField в реальной ситуации в базе данных , не в процессе именования схемы. Вот как mon goose может найти и заполнить!

Теперь я понимаю, что мне было трудно, что Virtual работает как-то в направлении, противоположном populate. Вы можете заполнить картинку, работая в виде дерева: она просто заполняется от id до документа, тогда как virtual заполняет документ, который не содержит ключа, тот, который содержит ключ, - тот, который будет добавлен в документ. процесс заселения: он как-то отсталый, то есть мне было так трудно gr asp! Заполняемый документ не имеет только что заполненного поля! это сногсшибательно!

Заключение и заключительные замечания

Тем не менее, я все еще считаю его ограниченным по сравнению с populate. Вы по-прежнему должны хранить локальные ключевые треки, что, например, не решает проблему памяти истории, и, по моим исследованиям, она более ограничена. Единственное преимущество, которое я вижу, это то, что вам не нужно использовать _id, вы можете использовать любой ключ, какой пожелаете. Я надеялся использовать для решения моей проблемы здесь Как сохранить файл JSON с помощью GridFs , но, поскольку нам все еще нужно хранить локальные ключи, я попал в ту же ловушку!

Исправление

Я рад сообщить, что я ошибался! Виртуалы потрясающие! и решает мой вопрос на Как сохранить файл JSON с помощью GridFs , я собираюсь обновить там!

...