0

My code simply is I want to let the user bookmark different types of products. This is on the user schema

const UserSchema = new mongoose.Schema({
// ...
bookmarks: [
    {
        product_type: { // this should be the refPath
            type: String,
            enum: ['vehicle', 'nutrition', 'accessory', 'etc...'],
        },
        product_id: {
            type: mongoose.Types.ObjectId,
            refPath: '' // Vehicle, Nutrition, etc..
        },
    },
  ]
});

How can I set the refPath to look on the property that is in the same object. or should I follow a different structure?

And how can I correctly populate the result.

Update 1:

I temporarily solved the problem by dividing the bookmarks as follows

bookmarks: {
    vehicle: [ mongoose.Schema.Types.ObjectId ],
    accessory: [ mongoose.Schema.Types.ObjectId ],
    ...
}

However this is not a very scalable solution

2 Answers2

0

refPath needs an absolute path to the field it references. Assuming bookmarks field is not a nested field:

const UserSchema = new mongoose.Schema({
// ...
bookmarks: [
    {
        product_type: {
            type: String,
            enum: ['vehicle', 'nutrition', 'accessory', 'etc...'],
        },
        product_id: {
            type: mongoose.Types.ObjectId,
            refPath: 'bookmarks.product_type' // relative path to the reference
        },
    },
  ]
});
0

refPath is an option that can be used in a schema definition to create a dynamic reference between two collections.

Suppose there are 2 types of products

const mongoose = require('mongoose');

const PhysicalProductSchema = new mongoose.Schema({
  // fields specific to physical products...
  name: String,
  price: Number,
});

const DigitalProductSchema = new mongoose.Schema({
  // fields specific to digital products...
  name: String,
  downloadUrl: String,
});

const PhysicalProduct = mongoose.model('PhysicalProduct', PhysicalProductSchema);
const DigitalProduct = mongoose.model('DigitalProduct', DigitalProductSchema);

module.exports = {
  PhysicalProduct,
  DigitalProduct,
};

to populate it in order schema you can do it this way

const Order = require('./order-model');
const { PhysicalProduct, DigitalProduct } = require('./product-models');

// find an order document where the product is digital
Order.findOne({ isDigital: true })
  .populate({
  // `populate()` works even though it references 2 models
    path: 'productId',
    },
  })
  .then(order => {
    console.log(order);
  })
  .catch(err => {
    console.error(err);
  });
Sehrish Waheed
  • 1,230
  • 14
  • 17