Why after populate array of values is becoming null? - javascript

I want to populate answers(comments) on my post . But on populating it becomes null while before that it stores fine of storing Id's of answer.
My schema of post
var doubtsSchema = new mongoose.Schema({
title : String,
content : String,
tags : String,
created : {
type : Date,
default : Date.now},
author : {
id : {
type : mongoose.Schema.Types.ObjectId,
ref : "User"},
username : String},
answers : [{
type : mongoose.Schema.Types.ObjectId,
ref : "Answers"}]});
module.exports = mongoose.model("Doubts",doubtsSchema);
My schema of answer
var answersSchema = new mongoose.Schema({
content : String,
created : {
type : Date,
default : Date.now},
author : {
id : {
type : mongoose .Schema .Types . ObjectId,
ref : "User"},
username : String},
likes_count : Number});
module.exports = mongoose.model("Answers",answersSchema);
Populate is not working
Doubts.findById(req.params.id).populate('answers').exec(function(err,foundDoubt) {
if(err) {
console.log(err);
} else {
console.log("here");
console.log(foundDoubt);
res.render("doubts/show",{doubt : foundDoubt});
}
});

I made a simple example, it works
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost:27017/test", {useNewUrlParser: true});
const UserSchema = new mongoose.Schema({
name: String,
comments: [{type: mongoose.Schema.Types.ObjectId, ref: "Comments"}]
});
const CommentSchema = new mongoose.Schema({
content: ""
});
const Users = mongoose.model("Users", UserSchema);
const Comments = mongoose.model("Comments", CommentSchema);
// Adding data
Promise.all([
new Comments({content: "test 1"}).save(),
new Comments({content: "test 2"}).save(),
new Comments({content: "test 3"}).save()
]).then(result => {
result = result.map(r => r._id);
new Users({name: "test", comments: result}).save().then(user => {
// Getting with populate
Users.findById(user._id).populate("comments").then(console.log);
})
}).catch(console.error);
In console:
{ comments:
[ { _id: 5c979d9dedc0b1db90fe81dd, content: 'test 1', __v: 0 },
{ _id: 5c979d9dedc0b1db90fe81de, content: 'test 2', __v: 0 },
{ _id: 5c979d9dedc0b1db90fe81df, content: 'test 3', __v: 0 } ],
_id: 5c979d9dedc0b1db90fe81e0,
name: 'test',
__v: 0 }
Maybe it will help to find the error

Related

MongoDB - how do I deep populate, an already populated field that has a reference to the schema it is in?

So I am having the following problem, I have a comments schema, which has a field called Replies and it is pointing toward the comment schema. The problem is that whenever I try to populate the following schema, everything except for the replies gets populated. Why is that happening, how do I fix it?
Comment Schema:
const {Schema, model} = require('mongoose')
const { ObjectId } = require('mongodb');
const commentSchema = new Schema({
Author:
{
type: ObjectId,
required: true,
ref: 'user'
},
Content:
{
type: String,
required: true
},
Likes:{
type: [ObjectId],
ref: 'user'
},
Replies: [this]
})
let comment = model('comment', commentSchema)
module.exports = comment
And that is how I populate the posts model:
let allPosts = await postModel
.find({})
.populate('Author Comments')
.populate(
(
{
path: 'Comments',
populate:[
{path: 'Author'}
]
},
{
path: 'Comments.Replies',
populate:[
{path: 'Author'}
]
}
)
)
and this is my post model, referenced in the previous code sample:
const {Schema, model} = require('mongoose')
const { ObjectId } = require('mongodb');
const postSchema = new Schema({
Author:
{
type: ObjectId,
required: true,
ref: 'user'
},
Content:
{
type: String,
required: true
},
Shares:{
type: [ObjectId],
ref: 'post'
},
Likes:{
type: [ObjectId],
ref: 'user'
},
Comments:{
type: [ObjectId],
ref: 'comment'
}
})
let post = model('post', postSchema)
module.exports = post

How to populate object with findById? CastError: Cast to ObjectId failed for value

I have MongoDB collections with post objects. The last one
{ "_id" : ObjectId("5f9fd72e6ec9ee294aec4ef1"), "comments" : [ "{\n _id: 5f9fd72e6ec9ee294aec4ef0,\n postedBy: 5f97c071bad24d1a81b25dd1,\n body: 'These were the days!',\n __v: 0\n}" ], "title" : "Vou comer voce! ", "body" : "What a wonderful life!", "postedBy" : ObjectId("5f97c071bad24d1a81b25dd1"), "createdAt" : ISODate("2020-11-02T09:53:50.652Z"), "__v" : 0 }
I want to add new commment.
I tried this way.
async function addComment() {
try {
const mycomment = await Comment.create({
postedBy : mongoose.Types.ObjectId('5f97c071bad24d1a81b25dd1'),
body: 'Here comes the new one!'
});
const post = await Post.findById(mongoose.Types.ObjectId('5f9fd72e6ec9ee294aec4ef1')).populate('comments');
} catch (err) {
console.log(err);
}
}
PostSchema
const PostSchema = new mongoose.Schema({
title: String,
body: String,
createdAt: {
type: Date,
default: Date.now,
},
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
comments: [{
type: String,
ref: 'Comment',
}]
});
Comments Schema
const CommentSchema = new mongoose.Schema({
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
title: String,
body: String,
});
Error in terminal
CastError: Cast to ObjectId failed for value "{\n' +
' _id: 5f9fd72e6ec9ee294aec4ef0,\n' +
' postedBy: 5f97c071bad24d1a81b25dd1,\n' +
" body: 'These were the days!',\n" +
' __v: 0\n' +
'}" at path "_id" for model "Comment"
Complete outout can be found here
How to add commments by using post _id?
The problem comes from
comments: [{
type: String,
ref: 'Comment',
}]
It should be:
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment'
}]

Finding users who has signed between given dates using Mongoose

I have user model like this
const guestSchema = mongoose.Schema({
facebook: {
id: String,
token: String,
email: String,
name: String,
phone: String,
dates: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "loginDate"
}
]
}
});
and loginDate model
const loginDateSchema = mongoose.Schema({
loginDate: Date
});
Every time user signs in current Date is added.
How can I find users who have signed in between given date?
I did below but I am getting empty result
Guest.find({ "facebook.id": { $exists: true } })
.populate("facebook.dates")
.find({ "facebook.dates": { $gte: startDate,$lte: endDate } })
.exec((err, foundUsers) => {
res.render("./admin/send", {
facebookUsers: foundUsers
});
});
Sample JSON
{
"_id" : ObjectId("5a1a838f58eb1a50c408de84"),
"facebook" : {
"email" : "sample#yahoo.com",
"name" : "Sample user",
"id" : "12345",
"dates" : [
ObjectId("5a1a838f58eb1a50c408de85"),
ObjectId("5a1a839258eb1a50c408de86"),
ObjectId("5a1a839358eb1a50c408de87"),
ObjectId("5a1a839758eb1a50c408de88"),
ObjectId("5a1aa17058eb1a50c408de8b")
]
},
"__v" : NumberInt(5)
}
LoginDate
{
"_id" : ObjectId("5a1a839358eb1a50c408de87"),
"loginDate" : ISODate("2017-11-26T09:04:19.107+0000"),
"__v" : NumberInt(0)
}
I think the issue is with your date which you are passing into find function on line
.find({ "facebook.dates": { $gte: startDate,$lte: endDate } })
You need to pass a date object and not a date string.
Here is my solution which is working fine for me
Facebook model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
var facebookSchema = new Schema({
id: String,
token: String,
email: String,
name: String,
phone: String,
logindate: Date
},
{
versionKey: false
}
);
module.exports = mongoose.model('Facebook', facebookSchema);
Here is data
[
{
"_id":"5a2949d40591a2192c8fad6b",
"logindate":"2016-10-10T06:28:37.146Z",
"phone":"03006351611",
"name":"mainuhassan",
"email":"mainuhassan#gmail.com",
"token":"MxuXmblL56aqt17aHh1rqcyeHc0E4CwQ",
"id":"100"
},
{
"_id":"5a294cd26c3e661514f3699e",
"logindate":"2015-10-10T06:28:37.146Z",
"phone":"03006351611",
"name":"mainuhassan1",
"email":"mainuhassan1#gmail.com",
"token":"MxuXmblL56aqt17aHh1rqcyeHc0E4CwQ",
"id":"100"
},
{
"_id":"5a294cfe75e2ba2778e9f249",
"logindate":"2017-10-10T06:28:37.146Z",
"phone":"03006351612",
"name":"mainuhassan2",
"email":"mainuhassan2#gmail.com",
"token":"MxuXmblL56aqt17aHh1rqcyeHc0E4CwQ",
"id":"100"
}
]
And here is my code for getting data between dates
Facebook.find({ logindate: { "$gte": new Date("2016-10-10T06:28:37.146Z"), "$lte": new Date("2017-10-10T06:28:37.146Z") } })
.exec(function(error, facebook){
if (!error) {
res.send(facebook);
}
});

.populate() not working

I have been working on this for hours and can't find a solution.
I am making a school directory using a
Student Model:
var mongoose = require("mongoose");
var studentSchema = new mongoose.Schema(
{
name: String,
courses: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Course"
}
]
});
module.exports = mongoose.model("Student", studentSchema);
and a Course Model...
var mongoose = require("mongoose");
var courseSchema = new mongoose.Schema (
{
name: String,
student: [
{
id:
{
type: mongoose.Schema.Types.ObjectId,
ref: "Student"
},
name: String
}
]
}
);
module.exports = mongoose.model("Course", courseSchema);
When I run .populate on a found student... it does not populate the Course values within the Student...
app.get("/students/:id", function(req, res){
Student.findById(req.params.id).populate("courses").exec(function(err, foundStudent){
if(err){
console.log(err);
} else {
console.log(foundStudent);
res.render("students/show", {student: foundStudent});
}
});
});
The console.log(foundStudent) will display...
{ _id: 597e7a49c945ee13529d0871,
name: 'Collin DeSoto',
__v: 1,
courses: [ { _id: 597e7a4dc945ee13529d0872 } ] }
AFTER the populate.. any ideas?
try this way
User.find(match, function (err, users) {
var opts = [{ path: 'company', match: { x: 1 }, select: 'name' }]
var promise = User.populate(users, opts);
promise.then(console.log).end();
})
and prefar this link link

How to change sub document after finding with mongoose

I have some code like below using mongoose.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/hoge');
var UserSchema = new Schema({
name: String,
children: [ChildSchema],
});
var ChildSchema = new Schema({
name: String,
}, {_id: false});
var User = mongoose.model('User', UserSchema);
var Child = mongoose.model('Child', ChildSchema);
User.findOne({_id: '52299322fdbbdec515000001'}, function(err, user) {
console.log(user);
for (var i=0; i<user.children.length; i++) {
var child = user.children[i];
child.name = 'newchild';
}
user.save(function(err) {
console.log(user);
mongoose.disconnect();
});
});
And here is my record in mongodb.
{
"name" : "u1",
"_id" : ObjectId("52299322fdbbdec515000001"),
"children" : [ { "name" : "c2" } ],
"__v" : 0
}
When I run the script, it outputs below.
{ name: 'u1',
_id: 52299322fdbbdec515000001,
__v: 0,
children: [ { name: 'c2' } ] }
{ name: 'u1',
_id: 52299322fdbbdec515000001,
__v: 0,
children: [ { name: 'newchild' } ] }
But my record in mongodb has not been changed. Why?
FYI, the record changed if I insert this code before saving.
user.children.push({name: 'somechild'});
Sorry, I've resolved myself.
The problem is the order of declarating Schemas.
It worked if I tried this change.
/* first, children's schema */
var ChildSchema = new Schema({
name: String,
}, {_id: false});
/* seconds, parent's schema */
var UserSchema = new Schema({
name: String,
children: [ChildSchema],
});

Categories

Resources