Reputation: 53
I have two collections into my MongoDB database: users and components.
The users' primary key is _id which is Number. It is referenced by the created_by and updated_by fields of a component document.
Everything works well except for the populate and I can't figure it out why. It leaves the value instead of the corresponding user document. I also tried to use ObjectIds instead of Numbers but nothing changed.
Any help will be appreciated.
I listed above the models and routing sources.
import mongoose from 'mongoose';
const userSchema = new mongoose.Schema({
_id: Number,
firstName: String,
lastName: String,
email: String,
password: String,
});
const User = mongoose.model('User', userSchema);
export default User;
import mongoose from 'mongoose';
const componentSchema = new mongoose.Schema({
name: String,
category: String,
package: String,
box: Number,
cell: Number,
quantity: Number,
note: String,
link: String,
created_by: {
type: Number,
ref: 'User'
},
created_on: Date,
updated_by: {
type: Number,
ref: 'User'
},
updated_on: Date
});
const Component = mongoose.model('Component', componentSchema);
export default Component;
import Component from './component';
import User from './user';
const models = { Component, User };
export default models;
import models from './models';
app.use((req, res, next) => {
req.context = { models };
next();
});
import { Router } from "express";
const router = Router();
...
var getComponents = async (req, res) => {
const query = req.context.models.Component.find().populate('users');
try {
const results = await query;
return res.status(200).send({ results: results });
} catch (err) {
return res.status(400).send({ error: err });
}
}
...
router.get('/', getComponents)
export default router;
I also tried to use the exec
var getComponents = (req, res) =>
req.context.models.Component.find().populate('users').exec().then(components => res.status(200).send({ results: components })).catch(err => res.status(400).send({ error: err }));
but I got the same result.
Upvotes: 0
Views: 181
Reputation: 17888
You just need to use an existing field name in populate path like .populate('created_by')
Here is the test:
I first created a user with this request body:
{
"_id": 111,
"firstName": "John",
"lastname": "River",
"email": "abc@def.net",
"password": "123123"
}
Then I created two components:
{
"name": "component 1",
"quantity": 1,
"created_by": 111
}
And
{
"name": "component 2",
"quantity": 2,
"created_by": 111
}
And using this code:
const result = await Component.find().populate("created_by");
The result is:
[
{
"_id": "5de7a89e9039c738b4008d41",
"name": "component 1",
"quantity": 1,
//other fields
"created_by": {
"_id": 111,
"firstName": "John",
"email": "abc@def.net",
"password": "123123",
"__v": 0
},
"__v": 0
},
{
"_id": "5de7a8aa9039c738b4008d42",
"name": "component 2",
"quantity": 2,
//other fields
"created_by": {
"_id": 111,
"firstName": "John",
"email": "abc@def.net",
"password": "123123",
"__v": 0
},
"__v": 0
}
]
Upvotes: 1
Reputation: 7969
you can do somthing like this.
created_by: { type:Schema.Types.ObjectId, ref: 'User' }
And query
Component.find().populate('created_by');
Upvotes: 1
Reputation: 2679
I believe it would be:
created_by: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
Then, query like this,
Component.find().populate('created_by');
Upvotes: 1