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
LVL 1
Black SulfurAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

arnoldCommented:
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.
Black SulfurAuthor Commented:
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.
arnoldCommented:
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.....
Black SulfurAuthor Commented:
Hi Arnold,

Here is the link:

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

And I took a screenshot too:

populate.png
arnoldCommented:
The example you posted has two ways to achieve the same result
the first seems to build and then exec the function.

the second example, defines what it is looking for and in the next steps, implicitly runs/execs the function.

you seem to have a working/functional approach.

You could create another aproach using exec function, execpopulate and then use debug (https://stackoverflow.com/questions/9910551/how-can-i-view-the-execution-plan-of-a-mongoose-js-query) on each approach to determine whose performance is better....

i can offer no such insight.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Node.js

From novice to tech pro — start learning today.