Link to home
Start Free TrialLog in
Avatar of Crazy Horse
Crazy HorseFlag for South Africa

asked on

using mongoose .populate()

I am used to php/mysql where I would just join tables but mongoose seems to be a whole other beast.

I have a product schema and a user schema.

here is product:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const productSchema = new Schema({
    title: {
        type: String,
        required: true
    },
    category: {
        type: String,
        required: true
    },
    image: {
        type: String,
        required: true
    },
    description: {
        type: String,
        required: true
    },
    userId: {
        type: Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },
    address: {
        city: {type: String, required: true }
    },
    createdAt: {
        type: Date,
        default: Date.now
    },
});

module.exports = mongoose.model('Product', productSchema);

Open in new window


And the user:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
    firstName: {
        type: String,
        required: true
    },
    lastName:  {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true,
        index: true,
        unique: true
    },
    contactNo: {
        type: String,
        required: true
    },
    password:  {
        type: String,
        required: true
    },
    address: {
        city: {type: String, required: true },
    }
});

module.exports = mongoose.model('User', userSchema);

Open in new window


When I as the admin user want to see the users first name and last name for the added product (as well as that product informatioN) I would to 'join' the 'tables' and based on the UserID in the product schema get the first name and last name from the users schema.

I am trying to use .populate here but not sure if it's correct or efficient.

exports.getApprove = (req, res, next) => {
    const productId = req.params.productId;
    Product.findById(productId)
    .populate('userId', 'firstName', 'lastName')
    .then(product => {
        res.render('account/approve', {
            pageTitle: 'Approve Listing',
            path: '/accounts/approve',
            product: product
        });
    })
    .catch(err => {
        console.log(err);
    });
};

Open in new window


console.log(product.userId.firstName);

Open in new window


Just wondering if I am not meant to use .exec() or .execPopulate() here
Avatar of arnold
arnold
Flag of United States of America image

Cfdo not ave mongodb experience, but a quick glance at https://www.sitepoint.com/using-joins-in-mongodb-nosql-databases/
Suggests like in other db's there does not seem to be a userid. Refereñce in your users table on whose basis in other DBs you would join table records.rt

Or product.userid to users._id as .....


With lack of exposure, I do not see an ID column in either table explicitly defined.
Avatar of Crazy Horse

ASKER

Hi Arnold, sorry for late reply. I my products table I have created a reference to the user:

    userId: {
        type: Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },

Open in new window


And then I am using populate() to basically do the join. It is working but I see in the documentation they have exec() and that was more what I was asking. Is that necessary? Why is it necessary etc.
Unfortunately, I do not have any experience with this mongodb could you provide the documentation reference that raised this question?
Potentially, the reference you saw/referred deals with using $lookup operator that preceded the populate() option.

https://mongoosejs.com/docs/populate.html

Perhaps the data aggregation process.....
Hi Arnold,

Here is the link:

https://mongoosejs.com/docs/populate.html

And I took a screenshot too:

User generated image
ASKER CERTIFIED SOLUTION
Avatar of arnold
arnold
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial