about mongoose populate relation a string field - node.js

I have two Schema
1 - User
UserSchema = new db.Schema({
email: {type: String, required: true},
pass: {type: String, required: true},
nick: {type: String, required: true},
admin: {type: String, default: ''},
reg: {type: Date, default: Date.now}
});
2 - Article
ArticleSchema = new db.Schema({
title: {type: String, required: true},
alise: {type: String},
time: {type: Date, defaults: Date.now},
view: {type: Number, defaults: 0},
author: {type: String},
content: {type: String},
classes: {type: db.Schema.Types.ObjectId, ref: 'Classes'},
user: {type: String, ref: 'User'}
});
I want ArticleSchema user field relation UserSchema nick.
my code:
Model.findOne({}).populate('classes user').exec(function(err, res){
if(err){
cb(err);
}else{
cb(null, res);
}
});
This is not working
message: 'Cast to ObjectId failed for value "tudou" at path "_id"'
What should I do?

Apparently you are using Mongoose, right?
If yes, to do it you must use db.Schema.Types.ObjectId in the ArticleSchema user field. So, your ArticleSchema should looks like this:
ArticleSchema = new db.Schema({
title: {type: String, required: true},
alise: {type: String},
time: {type: Date, defaults: Date.now},
view: {type: Number, defaults: 0},
author: {type: String},
content: {type: String},
classes: {type: db.Schema.Types.ObjectId, ref: 'Classes'},
user: {type: db.Schema.Types.ObjectId, ref: 'User'}
});
According to documentation:
There are no joins in MongoDB but sometimes we still want references to documents in other collections. This is where population comes in.
So, taking a look here, we can do something like that:
//To create one user, one article and set the user whos created the article.
var user = new UserSchema({
email : 'asdf#gmail.com',
nick : 'danilo'
...
});
user.save(function(error) {
var article = new ArticleSchema({
title : 'title',
alise : 'asdf',
user : user,
...
});
article.save(function(error) {
if(error) {
console.log(error);
}
});
}
And to find an article that was created for danilo:
ArticleSchema
.find(...)
.populate({
path: 'user',
match: { nick: 'danilo'},
select: 'email nick -_id'
})
.exec()
I suggest you to read about mongoose populate here

As of 4.5.0 You can use populate virtuals : http://mongoosejs.com/docs/populate.html#populate-virtuals
UserSchema = new db.Schema({
email: {type: String, required: true},
pass: {type: String, required: true},
nick: {type: String, required: true},
admin: {type: String, default: ''},
reg: {type: Date, default: Date.now}
});
ArticleSchema = new db.Schema({
title: {type: String, required: true},
alise: {type: String},
time: {type: Date, defaults: Date.now},
view: {type: Number, defaults: 0},
author: {type: String},
content: {type: String},
classes: {type: db.Schema.Types.ObjectId, ref: 'Classes'},
user: {type: String}
});
ArticleSchema.virtual('_user', {
ref: 'User', // The model to use
localField: 'user', // Find people where `localField`
foreignField: 'email', // is equal to `foreignField`
// If `justOne` is true, 'members' will be a single doc as opposed to
// an array. `justOne` is false by default.
justOne: true,
options: { sort: { name: -1 }, limit: 5 }
});
var User = mongoose.model('User', UserSchema);
var Article = mongoose.model('Article', ArticleSchema);
Article.find({}).populate('_user').exec(function(error, articles) {
/* `articles._user` is now an array of instances of `User` */
});

Related

Mongoose populate followers same document

I need to populate ObjectId parameters from the same Schema of users What am trying to do is I have 'Users' document and each record has followers and the ref is the same schema of users.
var userSchema = new Schema({
username: {type: String, unique: true, trim: true},
password: {type: String},
email: {type: String, trim: true},
avatar: {type: String},
fullname: {type: String},
bio: {type: String},
phone: {type: Number},
country: {type: String},
postal: {type: Number},
followers: [{ type: Schema.ObjectId, ref: 'User' }],
followed: [{ type: Schema.ObjectId, ref: 'User' }],
registered: {type: Date, default: Date.now}
});
var User = mongoose.model('users',userSchema);
Now when I tried to print the user information followers array return with ObjectId not the whole information
I try to print with this snippet
User.find().exec(function(error, groups) {
return res.status(200).send(groups);
});
What you want to achieve here is
User.find({})
.populate('followers')
.populate('followed')
.then(users => {
})
This will populate with both the followers and followed with their respective user objects

Populate nested array with Mongoose

I have a user schema as shown below and I'm trying to populate the live projects array but I can't figure out how to access it.
const userSchema = new Schema({
local: {
email: String,
username: String,
password: String,
liveProjects: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'liveProject'
}]
},
google: {
googleId: String,
email: String,
username: String,
liveProjects: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'liveProject'
}]
}
});
const User = mongoose.model('user', userSchema);
module.exports = User;
If it wasn't embedded I could just use
User.findById(id).populate('liveProjects').exec((err,projects)=>{});
But how do I get access to 'local.liveProjects' or 'google.liveProjects' so that I can populate them?
Turns out it is just as simple as
User.findById(id).populate('local.liveProjects').exec((err,projects)=>{});
User Schema Here
`let UserSchema = new Schema({
email: {
type: String,
unique: true,
required: true
},
password: {
type: String,
required: true
},
profile: {
firstName: {type: String,required: true},
lastName: {type: String,required: true},
address1: {type: String},
address2: {type: String},
city: {type: String},
state: {type: String},
zip: {type: String},
phone: {type: String,required: true},
avatar:{ type: Schema.Types.ObjectId, ref: 'Avatar'},
shippingAddress:{
address1: {type: String},
address2: {type: String},
city: {type: String},
state: {type: String},
zip: {type: String}
},
},
redemptionCards : [{ type: Schema.Types.ObjectId, ref: 'CardCodes' }]
});`
Logic to get RedemptionCards:-
User.findOne({ email }).populate("redemptionCards")
.exec(function (err, user) {
CardData.populate(user.redemptionCards, {path: 'redemptionCards',match: { _id: { $ne: null }}}, function (err, cards) {
console.log(cards);
});
FYI - CardData is the Hardcoded JSON file. Hope this helps.

reddit comment system how to replicate in mongodb/nodejs

How do I make nested comment replies in MongoDB/mongoose to create a comment system like in reddit nesting. Here are my schemas i created so far:
var CommentSchema = Schema({
body: {type: String},
chapterId: {type: RK, ref: 'Chapter'},
by: {type: RK, ref: 'User'},
}, {timestamps: true});
var UserSchema = new Schema({
name: String,
username: {type:String, unique: true},
profile_pic: String,
password: String,
role:{type: [{
type: String,
enum: ['user', 'admin']
}],
default: ['user']
}
});

Mongodb lookup with two ObjectId

I have a little issue getting lookup to work. It returns an empty array. I use contactId field in Billing Collection. And I use the contact _id created when entry in Contact Collection in mongodb (Can see it in Robomongo). I have few Billings with ContactId corresponding to the _id of few Contacts. Is my syntaxe correct ? Do I miss something ? Thank you for your help.
Below is my lookup syntaxe
Contact.aggregate([
{
$lookup: {
from: "Billing",
localField: "_id",
foreignField: "contactId",
as: "BillingMembership"
}
}
]).exec(function (err, contacts) {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
res.status(200).json({
message: 'Success',
obj: contacts
});
});
Below is the result I get back from the database.
(4) [Object, Object, Object, Object]
0:Object
BillingMembership:Array(0)
length:0
__proto__:Array(0)
additionalInterests:"MFM/REI"
billingEmail:"john#netdr.net"
cellPhone:6787025500
dateBirth:"1555-02-02T00:00:00.000Z"
firstName:"qtazerqr'efsg"
gogsMbrType:"Resident Applicant"
gogsYearJoined:"20111"
homePhone:6787025500
lastName:"gzaetrsg"
memberSuffix:", DO"
middleName:"fzerqgrre"
notes:"htrfjghdnt"
officeEmail:"john#netdr.net"
officePhone:6787025500
personalEmail:"john#netdr.net"
practiceId:"592e4c1638a494089c50c8c8"
praticeType:"MFM/High Risk"
spFirstNm:"gsertdhy"
spLastNm:"rthytrfgj"
spSuffix:"syhtdrh"
website:"trshdty"
__v:0
_id:"5932db29eb4dfe0de4a8a36d"
__proto__:Object
1:Object
2:Object
3:Object
Mongoose Schema Contact
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var mongooseUniqueValidator = require('mongoose-unique-validator');
var schema = new Schema({
firstName: {type: String, required: true},
middleName: {type: String, required: true},
lastName: {type: String, required: true},
dateBirth: {type: Date, required: true},
memberSuffix: {type: String, required: true},
officePhone: {type: Number, required: true},
homePhone: {type: Number, required: true},
cellPhone: {type: Number, required: true},
officeEmail: {type: String, required: true},
billingEmail: {type: String, required: true},
personalEmail: {type: String, required: true},
gogsMbrType: {type: String, required: true},
gogsYearJoined: {type: String, required: true},
spFirstNm: {type: String, required: true},
spLastNm: {type: String, required: true},
spSuffix: {type: String, required: true},
notes: {type: String, required: true},
praticeType: {type: String, required: true},
additionalInterests: {type: String, required: true},
website: {type: String, required: true},
practiceId: {type: Schema.Types.ObjectId, ref: 'Practice'}
});
schema.plugin(mongooseUniqueValidator);
module.exports = mongoose.model('Contact', schema);
Mongoose Schema Billing
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var mongooseUniqueValidator = require('mongoose-unique-validator');
var schema = new Schema({
reason: {type: String, required: true},
amount: {type: Number, required: true},
membership: {type: String, required: true},
membershipYear: {type: Schema.Types.ObjectId, ref: 'Membership'},
type: {type: String, required: true},
date: {type: String, required: true},
contactId: {type: Schema.Types.ObjectId, ref: 'Contact'},
conferenceId: {type: Schema.Types.ObjectId, ref: 'Conference'}
});
schema.plugin(mongooseUniqueValidator);
module.exports = mongoose.model('Billing', schema);
Solved. thanks to Veeram.
I used Change your from: "Billing" to from: "billings"

How to take only articles by given user Express.js

I want to display in my user/myarticlesview only articles by logged in user.
How can i do that:
Here is my User model and Article schema:
let userSchema = mongoose.Schema(
{
email: {type: String, required: true, unique: true},
passwordHash: {type: String, required: true},
salt: {type: String, required: true},
articles: [{type: ObjectId, ref: 'Article'}],
roles: [{type: ObjectId, ref: 'Role'}]
}
);
let articleSchema = mongoose.Schema (
{
author: {type: ObjectId, ref: 'User'},
title: {type: String, required: true },
content: {type: String, required: true },
phone: {type: Number, required: true },
date: {type: Date, default: Date.now() }
}
);
I want to do this in my userController and passed it to the view:
myArticlesGet: (req, res) => {
if (!req.isAuthenticated()) {
res.redirect('/');
return;
}
res.render('user/myarticles')
}
I cant figure it out how to make the query.Thank you.
As you are using express sessions you can store userId in the express session when the user is authenticated and then you can get user articles from user like that
User.find({_id: req.session.userId}).populate('articles')

Resources