Mongoose Populate not populating the data - node.js

The following are two blocks of code, the first one is my Schema and the second one is my query. The Payment model is getting saved and it has the id referring to the user. Can I know where I am going wrong, is there any thing wrong with the fundamental ?
Here is my schema of User and Payment
User:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
var paymentSchema = new Schema({
amount: Number,
user: {
type: Schema.Types.ObjectId,
ref: 'User'
}
});
var userSchema = new Schema({
email: String,
payment: {
type: Schema.Types.ObjectId,
ref: 'Payment'
}
});
module.exports = mongoose.model('User', userSchema);
module.exports = mongoose.model('Payment', paymentSchema);
Here is my query which I am using to populate using promise:
User.findOne({email: req.query.email})
.populate('payment')
.select('_id payment')
.then(function(user) {
res.json(user);
});

Related

Trying to populate mongoose schemas

This issue seems to be common but the answers for it vary. I am trying to populate these two models with their data.
const express = require('express');
const mongoose = require('mongoose');
const app = express();
app.listen(4000,()=>{
console.log('server listening on port 4000')
});
mongoose.connect('mongodb://localhost:27017/testDB',{useNewUrlParser:true, useUnifiedTopology: true, useCreateIndex: true, useFindAndModify:true });
const UserSchema = new mongoose.Schema({
username: String,
})
const PostSchema = new mongoose.Schema({
content: String,
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
}
})
const Post = mongoose.model('Post', PostSchema);
const User = mongoose.model('User', UserSchema);
const user = new User({
username: 'alex antoine',
})
const posts = new Post({
content: 'I hope this works'
})
UserSchema.virtual('Post',{
localField: '_id',
foreignField: 'author',
ref:'Post',
})
const populateUser = async(username)=>{
const user = await User.findOne({username}).populate('posts');
const userPopulated = await user.populate('Post').execPopulate();
console.log(userPopulated);
}
const save = async()=>{
user.save();
posts.save();
}
save();
populateUser('alex antoine');
The response I received from this is
Populated User {
posts: [],
_id: 60dbe989fd1ab074d0ab0541,
username: 'alex antoine',
__v: 0
}
This seems to be a common issue that a lot of people had but none of their answers seems to work for me. Thanks in advance.
You're not declaring your user's posts as a virtual field right. Your PostSchema is correct, but your UserSchema should look like this:
const UserSchema = new mongoose.Schema({
username: String
})
UserSchema.virtual('posts', {
ref: Posts,
localfield: '_id',
foreignField: 'author'
});
This way, when dealing with a user document, you can populate its posts:
user.populate('posts').execPopulate();
result User.findOne({username}).populate('posts').exec();
// At the exec() try using execPopulate()
Then at the ref add the required: true` option

mongoose find in subdocument with $and statement

I want to find and update only one object in my array of object, that I try to findAndUpdate:
So I want to find my document with correct name and password, and then find only one subdocument, that I want update/save into
logic:
roomModel.findOneAndUpdate({ $and: [{ name: req.body.roomName }, { password: req.body.roomPassword }], 'users.name': req.body.userName }, {
'$set': {
'users.$.latitude': req.body.latitude,
'users.$.longitude': req.body.longitude,
'users.$.updateDate': new Date()
}
})
.then((room) => {
// ...
})
roomModel:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = require('./user').userSchema;
var room = new Schema({
name: String,
password: String,
users: [userSchema]
});
module.exports.roomSchema = room;
module.exports.roomModel = mongoose.model('room', room);
userModel:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var user = new Schema({
name: String,
latitude: String,
longitude: String,
updateTime: Date
});
module.exports.userSchema = user;
module.exports.userModel = mongoose.model('user', user);
I don't exactly know how to perform that and search along with subdocument search

How to deal with mongoose nested population?

I am trying to make some nested population. User model is populated the way i expect it to be.
But i am having trouble with nested population of a Post model. It's not populated at all.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
mongoose.connect(`mongodb://localhost:27017/testDB`);
var UserSchema = new Schema({
name:String,
post: {
type: Schema.Types.ObjectId,
ref: 'Post'
}
});
var PostSchema = new Schema({
title:String,
subscriber:{
type:Schema.Types.ObjectId,
ref:'Subscriber'
}
});
var SubscriberSchema = new Schema({
name:String
});
var User = mongoose.model("User", UserSchema);
var Post = mongoose.model('Post',PostSchema);
var Subscriber = mongoose.model('Subscriber',SubscriberSchema);
User
.find()
.populate([{
path:'post',
model:'Post',
populate:{
model:'Subscriber',
path:'subscriber'
}
}])
.exec()
.then(function(data){
console.log(data);
mongoose.disconnect();
});
You are calling .populate incorrectly.
Please try this:
User
.find()
.populate('post')
.populate({
path: 'post',
populate: {
path: 'subscriber',
model: 'Subscriber'
}
})
.exec()
.then(function (data) {
console.log(data);
mongoose.disconnect();
});
For more info check this out.

Populating array of ObjectId's in Mongoose 3.8

I'm trying populate an array with entire information of another collection and I can't get it.
I have 2 collections: users and exams and I want to show a json response containing user information and exams buyed by the user.
My problem is that I don't know how to populate examsPurchased with entired exams information (name,numberOfQuestions,yearOfExam...)
¿How can I do that?
This is my final result
And this is my code
// USER MODEL
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// Schemas
var userSchema = new Schema({
name : String,
hobbies: {
name : String,
ubicacion:String
},
examsPurchased : [new Schema({
exams: {type: Schema.ObjectId, ref: 'exams'}
})]
});
module.exports = mongoose.model('users', userSchema);
// EXAM MODEL
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// Schemas
var examSchema = new Schema({
year : Number,
count : Number
});
module.exports = mongoose.model('exams', examSchema);
// ROUTES
router.route('/user/:user_id').get(function(req,res){
user
.findById(req.params.user_id)
.populate('examsPurchased._id')
.exec(function (err, completeUser) {
if(err) {
console.log(err);
}
res.send(completeUser);
});
});
The problem is that you aren't populating the good field:
// ROUTES
router.route('/user/:user_id').get(function(req,res){
user
.findById(req.params.user_id)
.populate('examsPurchased.exams', 'year count') // Line changed
.exec(function (err, completeUser) {
if(err) {
console.log(err);
}
res.send(completeUser);
});
});

Mongoose Populate callback undefined

I am running a query in Mongo so that I can only display all subcollections of the schema except for the account ID. However, I get undefined as the result of the callback "list_data". This is how my query is written in my routes:
exports.list_data = function(req, res){
models.Director.find({})
.populate("full_name").populate("dob").populate("favorite_movies").populate("favorite_camera")
.exec(function(err, list_data){
res.render('users', {"dirs": list_data});
})
};
this is my models:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/lvsAPI');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
//set schema
var Schema = mongoose.Schema;
var directorSchema = new Schema ({
account_id: Number,
full_name: String,
dob: Date,
favorite_camera: String,
favorite_movies: String
});
var Director = mongoose.model("Director", directorSchema);
module.exports = {"Director": Director};
This is simple no results.
And your schema wrong for use populate().
Please see official docs and just do it right:
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var personSchema = Schema({
_id : Number,
name : String,
age : Number,
stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});
var storySchema = Schema({
_creator : { type: Number, ref: 'Person' },
title : String,
fans : [{ type: Number, ref: 'Person' }]
});
var Story = mongoose.model('Story', storySchema);
var Person = mongoose.model('Person', personSchema);
The ref option is what tells Mongoose which model to use during population.
Now 'ref' fields will be populated:
Story
.findOne({ title: 'Once upon a timex.' })
.populate('_creator')
.exec(function (err, story) {
if (err) return handleError(err);
console.log('The creator is %s', story._creator.name);
// prints "The creator is Aaron"
})
Population docs

Resources