Mongoose Finding data in Sub document - node.js

I have this model
//user notif schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserNotifSchema = new mongoose.Schema({
NotifType : {type : Number},
NotifData : {
User_source_id : {type : Schema.Types.ObjectId, ref : 'User'}, // for course, forking
Course_id : {type : Schema.Types.ObjectId, ref : 'Course'}, // for course
UserFile_id : {type : Schema.Types.ObjectId, ref : 'UserFile'} // for forking
},
NotifTarget : [
{type : Schema.Types.ObjectId, ref : 'User'}
],
Created_at : {type : Date, required : true, default : Date.now},
});
var UserNotif = mongoose.model('UserNotif', UserNotifSchema);
module.exports = UserNotif;
I create a model that contains user notification by NotifTarget. I want to get some notif to specific user and doing like this
var user_id = req.session.userLogin.UserId;
NotifModel.find({'NotifTarget' : user_id})
.populate('NotifTarget')
.exec(function(err, doc){
if (err){
res.send(err);
}
else{
res.send(doc);
}
})
This is ok when there only one array user_id in NotifTarget but return empty array when I give multiple data in NotifTarget. Are there any solution for this?

Related

Is it possible to design such schema in MongoDB ? If not any suggestions?

I am trying to develop such a schema in MongoDB.
var subCategorySchema = new Schema({
_id: ObjectId,
name : String,
});
var categorySchema = new Schema({
name : String,
category : {
type : Schema.Types.ObjectId,
ref : 'subCategories'
},
});
var postSchema = new Schema({
name : String,
category : {
type : Schema.Types.ObjectId,
ref : 'categories'
},
subCategory : {
type : Schema.Types.ObjectId,
ref : 'categories'
}
});
The issue is that how can I directly populate sub category in post ?

Mongoose virtuals in array of subdocument

Is there a way to "get" the value a document's field in the subdocuments?
book_id is in the main document,how to get the value of it here
'''
const ExtraElements_Schema = new Schema({
label : {type : String, requires : true},
page : {type : Number},
id_resource : {type : Number, required : true},
description : {type : String}
},{toJSON : {virtuals : true , getters : true}})
ExtraElements_Schema.virtual('path').get(function(){
const host = global.gConfig.thisServerHost;
return `${host}/${this.book_id???}/${this.id_resource}`
})
const Extra_Schema = new Schema({
label : {type : String, required : true},
book_id : {type : Number},
id_extra : {type : Number, required : true},
extras : [ExtraElements_Schema]
})
You can use virtuals for this too.
ExtraElements_Schema.virtual('book', {
ref: bookTableName,
localField: 'book_id',
foreignField: '_id', // Change this if it's not the id that is saved
justOne: true
});
And one thing that bugged me a little I couldn't see the virtuals with console.log I should always use console.log(model.toJSON()) to see the virtuals

some error in using $push in mongodb

my Schema is
var User = new mongoose.Schema({
//general information
name : {type:String},
email : {type : String},
number : {type : String},
password : {type:String},
//featured information
path: { type: String},
dob : {type:String},
gender : {type : String},
blood_group : {type:String},
marital_status : {type : String}
});
module.exports = mongoose.model('user',User);
i want to use update some details by-
app.post('/contactinfo',function (req,res) {
var name = req.body.name;
var number = req.body.number;
var email = req.body.email;
User.update({_id : userID},{
$push : {
name : name,
number : number,
email : email
}
},{new : true },function (err,result) {
if(err){
console.log(err);
}
else{
console.log(result);
res.send({status : "success" , message : "Details updates"});
}
});
});
I don't define array anywhere
but the problem is that is show error on updating
{ MongoError: The field 'name' must be an array but is of type string in document {_id: ObjectId('5a0880e2d767e8131807e7f4')}
I am stuck here
please someone help me in solving this error
You just have to change your $push to $set. That's it.

Mongoose- How to use discriminators in subdocument

I want the output to be like this
var FeedSchema = new Schema({
timestamp : {type : String, required : true},
feed_type_code : {type : Number, required : true},
gender : {type : String, required : true},
feed_item : Article || Tip || etc.
}
Hence, I understand I have to use discriminators. I followed the following SO answer
Here is what I did:
var feed_type = {discriminatorKey : 'feed_item'};
var FeedSchema = new Schema({
timestamp : {type : String, required : true},
feed_type_code : {type : Number, required : true},
gender : {type : String, required : true}
}, feed_type);
var TipSchema = new Schema({
tip : {type : String, required : true},
subtip : {type : String, required : true},
display_count : {type : Number},
likes : {type : Number}
}, feed_type);
var ArticleSchema = new Schema({
title : {type : String, required : true},
english_title : {type : String, required : true},
image_url : {type : String, required : true},
article_text : {type : String, required : true},
english_article_text : {type : String},
author : {type : String},
english_author : {type : String}
}, feed_type);
Here is how I am saving the document:
var article = new Article({
title : req.body.title,
english_title : req.body.english_title,
image_url : req.body.image_url,
article_text : req.body.article_text,
english_article_text : req.body.english_article_text,
author : req.body.author,
english_author : req.body.english_author
});
var feed = new Feed({
gender : req.body.gender,
timestamp : moment().valueOf(),
feed_type_code : 9002,
feed_item : article
});
feed.save(function(err, doc){
if(err){
res.json({success : -1});
return;
}
res.json({success : 1, feed : doc});
});
I am not getting the article output for this:
{
"success": 1,
"feed": {
"__v": 0,
"gender": "female",
"timestamp": "1481460218959",
"feed_type_code": 9002,
"_id": "584d49faa6ff3a23bc868ab3"
}
}
I am new to Nodejs. I would appreciate if you can point out the error.
in the model file add these lines
var Feed = mongoose.model('Feed', FeedSchema, 'feed');
var Article = Feed.discriminator('Article', ArticleSchema);
var Tip = Feed.discriminator('Tip', TipSchema);
module.exports = {
Feed : Feed,
Article : Article,
Tip : Tip
}
This is how you save the document. You don't need to create a separate Feed object.
var article = new Article({
gender : req.body.gender,
timestamp : moment().valueOf(),
feed_type_code : 9002,
title : req.body.title,
english_title : req.body.english_title,
image_url : req.body.image_url,
article_text : req.body.article_text,
english_article_text : req.body.english_article_text,
author : req.body.author,
english_author : req.body.english_author
});
article.save(function(err, doc){
if(err){
console.log(err);
res.json({success : -1});
return;
}
res.json({success : 1, feed : doc});
});

How to populate array of objects with Mongoose

I have the following schemas in mongoose:
var documentsSchema = new Schema({
"document" : {
"_project" : {
type : Schema.ObjectId,
ref : 'Projects'
},
"_addedBy" : {
type : Schema.ObjectId,
ref : 'Users'
},
"_associateUsers" : [{
type : Schema.ObjectId,
ref : 'Users'
}],
"_codes" : [{
type : Schema.ObjectId,
ref : 'Codes'
}],
"paragraphTitle" : String,
"paragraphText" : String,
"memos" : [
{
"_addedBy" : {
type: Schema.Types.ObjectId,
ref: 'Users'
},
"memoData" : String
}
]}});
and the Codes:
var codesSchema = new Schema({
"code" : {
"_addedBy" : {
type : Schema.ObjectId,
ref : 'Users'
},
"codeText" : String,
"codeWeight" : Number
}});
I need to populate _codes.codeText (or codes fields) of the all elements of the array, but looks like I am not doing it properly.
Documents.find({
"document._project": element._id
}).
populate('document._codes.code','codeText').
exec(function (err, result) { .... }
this and various tries with populate arguments are either not populating the fields or not returning any data.
What am I doing wrong?
You have defined the schema, but not the model. The _codes has a ref to the model Codes but it doesn't exists. When you call .populate with the first two params it assumes that the model is Codes (taked from reference)
To fix this, toy need to add:
mongoose.model('Codes', codesSchema);
mongoose.model('Documents', documentsSchema);
Maybe you need to do the same with Users
See the complete documentation for populate here
P.S. A recommendation: If you are defining an schema for codes or whatever you don't need to define again the name of the object as part of the same schema, look:
From this
//your style
var catsSchema = new Schema({
"cat" : {
"attr1" : {type: ...},
"attr2" : {type: ...}
}
});
to this
//obviously attr1 and attr2 are part of cat object/document
var catsSchema = new Schema({
"attr1" : {type: ...},
"attr2" : {type: ...}
});

Resources