Mongoose population - javascript

I have this Mongoose Schema
var ItemSchema = new Schema({
"name":String,
"review": [{ type: Schema.Types.ObjectId, ref: 'Reviews'}]
});
and the schema of the review is:
var ReviewSchema = new Schema({
"title": String,
"user": { type: Schema.Types.ObjectId, ref: 'Users' }
});
and the schema of the users is:
var UserSchema = new Schema({
"name":String,
"surname":String,
});
This is the code to get the item:
Item.findOne({_id:req.params.idItem})
.populate('review')
.exec(function (err, item) {
console.log(item);
});
But this code only populates the reviews, and I want that to populate also the user.

Item.findOne({_id:req.params.idItem})
.populate({
path: 'review',
populate: {
path: 'user'
}
})
.exec(function(err, item) {});
http://mongoosejs.com/docs/populate.html#deep-populate

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

changing array inside the collection mongoDB

I am trying to change an array in my collection of users according to the id of an object I have in my array
it looks like this
_id:60a54bb0a5c5d25c9f4b83ea
email:"timotej"
pass:"$2b$10$hdvMb.PrcRmwNCqxcLpOmOLTvRTrMzHWAhPHWa4o4E.qOfuDTjeAm"
createdAt:2021-05-19T17:32:32.792+00:00
updatedAt:2021-05-23T11:32:37.882+00:00
__v:0
contacts:Array
0:Object
_id:"60aa3d3db9344014e5944291"
name:"contact1"
email:"contact1#mail.com"
phone:"0"
1:Object
_id:"60aa3d55b9344014e5944292"
name:"contact2"
email:"contact2#mail.com"
phone:"00"
Shema:
const mongoose = require('mongoose')
const Schema = mongoose.Schema;
const userSchema = new Schema({
email: {
type: String,
required: true,
unique: true
},
pass:{
type: String,
required: true
},
contacts:{
_id: {
type: String,
unique: true
},
name:{
type: String,
},
email:{
type: String
},
phone:{
type: String
}
}
}, {timestamps: true})
const User = mongoose.model('User', userSchema)
module.exports = User;
here is my code, I am trying to find the user by its email, and then the object in array contacts by its id and then update the contact.
const user = User.findOneAndUpdate(
{ email: mail.toLowerCase(), "contacts._id": req.params.id},
{ $set:{
"contacts.$._id": req.params.id,
"contacts.$.name": req.body.name,
"contacts.$.email": req.body.email,
"contacts.$.phone": req.body.phone,
}
},
{ multi: false }
).then((result) => {
console.log("result : " + result)
the data in req should be ok, but nothing is changing in my db when i send request

Mongo populate in optional field giving cast error

I have a 'vendor' and 'media' collection, media collection store vendor profile images and that is not mandatory field for vendors. Some vendors have profile picture some not, I want to list all vendors including their profile pictures reference. But I'm getting cast error when I populate profilePicture from meidas. I have other populate like 'userId', 'venueId' those are mandatory fields and it works.
Error:
CastError: Cast to ObjectId failed for value "xyz" at path "_id" for model "medias" undefined
Find Query:
const result = await resultObject.skip(skip)
.populate('userId')
.populate('venueId')
.populate('profilePicture')
.limit(parseInt(obj.pageSize, 10))
.sort({ [obj.sortColumn]: parseInt(obj.sortValue, 10) });
return result;
medias model
const MediasModel = () => {
const MediasSchema = new mongoose.Schema({
url: { type: String, required: true },
key: { type: String},
}, { timestamps: { createdAt: 'createdDate', updatedAt: 'modifedDate' } });
return mongoose.model('medias', MediasSchema);
};
module.exports = MediasModel();
vendors model
const Vendors = new mongoose.Schema({
venueId: { type: mongoose.Schema.Types.ObjectId, ref: 'venues' },
userId: { type: mongoose.Schema.Types.ObjectId, ref: 'users' },
name: { type: String, required: true },
profilePicture: { type: mongoose.Schema.Types.ObjectId, ref: 'medias' },
}, { timestamps: { createdAt: 'createdDate', updatedAt: 'modifedDate' } });
module.exports = mongoose.model('vendors', Vendors);
Try the below code
const Vendors = require('path/to/model_vendor');
Vendors.find()
.populate([{path: 'venues'}, {path: 'users'}, {path: 'medias'}])
.skip(skip_value)
.limit(limit_value)
.sort({condition: 1 }) // Modify according to your need
.exec().
.then(vendors=>{
console.log(vendors)
}).catch(err=>{
console.log(err)
})

.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

Mongoose populate embedded document in cascade

I am modeling a 'friends' relationship between the user of my micro-blog app. It looks something like this:
in the user.js file
var db = require('mongoose')
, Schema = db.Schema
, ObjectId=Schema.ObjectId;
var userSchema = new Schema({
name:{firstname:String,surname:String},
birthdate:String,
email:String,
posts: [new Schema({
timestamp:Date,
post:{type: ObjectId, ref: 'Post'}
})],
friends: [new Schema({
friend: {type:ObjectId, ref:'User'}
})]
});
module.exports = db.model('User', userSchema);
in the post.js file
var db = require('mongoose')
, Schema = db.Schema,
ObjectId=Schema.ObjectId;
var postSchema = new Schema({
title:String,
content:String,
});
module.exports = db.model('Post', eventSchema);
What I want to achieve is to get all the current user's friends, with their posts array of embedded document, already populated. I clumsily tried with this function:
function getUserFriendsPost(req, res) {
var count = 0;
var output = new Array();
User.findOne({
_id: req.params.id
}, function(err, user) {
for (var i = 0; i < user.friends.length; i++) {
User.findOne({
_id: user.friends[i].friend
}).populate('posts.post').exec(function(err, post) {
output.push(post);
count++;
if (count==user.friends.length) {
res.send(output);
}
});
}
});
}
What I get instead is the friends array correctly returned but the element of the posts having value of null, like this:
[
{
"_id": "4fd5e5f3e45fd10100000004",
"birthdate": "11/11/1911",
"email": "blablabla#gmail.com",
"friends": [],
"posts": [
{
"timestamp": "2012-04-12T16:47:14.576Z",
"post": null,
"_id": "4f870712c488cf0100000081"
},
{
"timestamp": "2012-04-12T16:48:42.282Z",
"post": null,
"_id": "4f87076ac488cf01000000a3"
},
{
"timestamp": "2012-04-12T16:56:26.062Z",
"post": null,
"_id": "4f87093ac488cf0100000117"
}
"name": {
"firstname": "John",
"surname": "Doe"
}
}
]
Is there something that I am overlooking the in populate mechanism or should I proceed with a different approach?
Thank you
With any luck we will get recursive populating in Mongoose 3.0. Until then consider duplicating the data you want from the post (likely only the title) and storing it like this:
var db = require('mongoose')
, Schema = db.Schema
, ObjectId = Schema.ObjectId;
var userSchema = new Schema({
name: {firstname: String, surname: String},
birthdate: String,
email: String,
posts: [new Schema({
timestamp: Date,
title: String,
post: {type: ObjectId, ref: 'Post'}
})],
friends: [new Schema({
friend: {type: ObjectId, ref: 'User'}
})]
});
module.exports = db.model('User', userSchema);
Then you can do a regular:
User.findOne({_id: req.params.id}).populate('friends').exec(function(err, user) { ... })

Categories

Resources