T
T
triggerfinger2017-12-15 01:42:34
MongoDB
triggerfinger, 2017-12-15 01:42:34

How to refer from one scheme to the second one?

There are two models (in two files): Brand.jsandProduct.js

const brandSchema = new mongoose.Schema ({
  name: String,
  image: String
})

const productSchema = new mongoose.Schema ({
  name: String,
  image: String,
  brand: { тут обратится к brandSchema }
})

Two questions arose: how do I productSchemaeven know which one brand.nameto contact? It turns out that I have to get either a list of all available brands in advance (like the GUI in the CMS admin panel), or in another way a sign to which document to refer to? For example, searching for just matches name
. And the second question is how to arrange it correctly without code duplication (so that they are in separate files).
I do populaten’t find anything at all, and I didn’t find the answer in the documentation.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Abcdefgk, 2017-12-15
@triggerfinger

const Schema = mongoose.Schema; //так просто удобнее

const brandSchema = new Schema ({
  name: String,
  image: String
});

const productSchema = new Schema ({
  name: String,
  image: String,
  brand: { type: Schema.Types.ObjectId, ref: 'Brand' } // этот ref ссылается на имя модели, которое будет ниже
});

var Brand = mongoose.model('Brand', brandSchema); // вот оно, это имя в казычках
var Product = mongoose.model('Product', productSchema);

Now, when saving a document with a product, in the brand field, it must be passed the id of the brand to which it belongs.
var briony = new Brand({
  name: "Briony",
  image: ".../briony.jpg"
});
var shapka = new Product({
  name: "Shapka",
  image: "...../shapka.jpg",
  brand: briony // тут id брэнда этой шапки (как показал чувак в том ответе - и я проверял - mongoose сам сообразит именно id брэнда вписать по переменной briony, но можно и явно - briony._id)
});
briony.save();
shapka.save();

It's just a pointless use populate. Its meaning is not to transfer to the document a lot of information about the document associated with it - when there is really a lot of this information. And there are only two lines: the name and a link to the logo.
It could mean the opposite. Add a field to the branding scheme:
const brandSchema = new Schema ({
  name: String,
  image: String,
  products: [{ type: Schema.Types.ObjectId, ref: 'Product' }]
});

And having saved the shapka document to the database, here we push its ID to the array of products from Briony:
var briony = new Brand({
  name: "Briony",
  image: ".../briony.jpg"
});
briony.products.push(shapka._id);

Now, in the products field, the document named Briony will not have an array of large objects with product names, descriptions, prices, etc., but an array of only product IDs related to this brand.
And vice versa. If the brand scheme involves not only its name and picture, but also some other description, a long history, etc., then all this should not be entered into the product document, but only the brand id should be entered, and all this detailed dregs should be requested in while querying the shapka document using just populate:
Product
  .findOne({ name: 'Shapka' })
  .populate('brand') // это означает "заселить", т.е. по айдишнику, вписанному в поле brand продукта, найти в коллекции брендов - нужный брэнд и вывалить сюда всю о нём информацию
  .exec ... // и т.д.

Or
Product
  .findOne({ name: 'Shapka' })
  .populate('brand', 'image')
  .exec ... // и т.д.

if the brand needs only its picture no primer.
(or just his name - .populate('brand', 'name')
Something like that.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question