Mongoose- How to use discriminators in subdocument - node.js

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});
});

Related

how to update specific subdocument in array with mongoose

postSchema
let postSchema = new mongoose.Schema({
data : Buffer,
contentType : String,
caption : String,
likes : [mongoose.ObjectId],
likesCount : {type :Number, default : 0},
comment :[{userId :mongoose.ObjectId, cmnt : String, reply :[{}]}],
commentCount : {type :Number, default : 0},
date : {type : Date, default: Date.now}
})
userSchema
let userSchema = new mongoose.Schema({
qr : {
data : Buffer,
contentType : String
},
profile_pic:{
data:Buffer,
contentType : String
},
first_name:String,
last_name:String,
email:{
type:String,
unique:true
},
mobile_number:Number,
DOB : Date,
gender:{
type : String,
enum : ["Male","Female","Other"]
},
password : {
type : String
},
address:{
city : String,
state : String
},
followers : {
type : [mongoose.ObjectId]
},
followersCount : {
type : Number,
default : 0
},
following : {
type : [mongoose.ObjectId]
},
followingCount : {
type : Number,
default : 0
},
//this is my post schema
posts : [postSchema],
postsCount :{type :Number, default : 0},
reset_password_token : {
OTP:Number,
is_varify_password_token : {
type:Boolean,
default : false
},
time : {
type : Date,
}
}
})
** 1) i want to find specific user
2) after finding user i want to find and update specific post (caption) in array of posts **
i have tried but not working
await USERMODEL.findOneAndUpdate({_id:req.user._id,posts:{$elemMatch:{_id: req.params.postId}}},{"posts.$.caption ":caption})mongodb document image
PLEASE HELP I AM NEW TO MONGODB
**by mistake I have pasted some code out of block please do not mind **
It looks like your post is mostly code; please add some more details

How to specify and update an object within array in MongoDB

I'm trying to update the values of an object placed inside the array.
The MongoDB schema is as follows:
const ServiceStatus = new Schema({
CustomerName : { type : String},
CustomerNumber : {type : String},
ServiceName : {type : String},
Details : {type: String},
Date : {type: String},
Status : {type : String},
Comments : {type : String},
ServiceId : {type: Schema.Types.ObjectId},
CustomerId : {type: Schema.Types.ObjectId},
ServiceProvider : {type: Schema.Types.ObjectId},
message : [{
sender : {type: String},
content : {type : String},
time : {type : String}
}]
})
and the snippet of the route is
router.put('/message/customer/:id',(req, res) => {
const id=req.params.id;
Status.findByIdAndUpdate({_id : id},
{
$push : {
"message.$.sender": "Customer" ,
"message.$.content": req.body,
"message.$.date" : new Date()
}
}
,{ useFindAndModify: false } )
.exec((err, status) => res.json(status))
})
When I tried running it on postman it doesn't get updated but I don't get any error. I want to know how I should change the router to make it work.
I think it should be like this one:
db.ServiceStatus.insertOne(
{
CustomerName: "the name",
message: [{ sender: "Customer", content: "some content", time: new Date() }]
}
);
db.ServiceStatus.updateOne(
{ CustomerName: "the name" },
{
$push: {
message: { sender: "Another customer", content: "more content", time: new Date() }
}
}
)
db.ServiceStatus.find()
{
"_id" : ObjectId("5fdc4f14d1d3de1f92780a0b"),
"CustomerName" : "the name",
"message" : [
{
"sender" : "Customer",
"content" : "some content",
"time" : ISODate("2020-12-18T07:41:24.166+0100")
},
{
"sender" : "Another customer",
"content" : "more content",
"time" : ISODate("2020-12-18T07:41:26.328+0100")
}
]
}

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.

Display _id as the first element of a subdoc in mongodb

I have a document with subdoc, with each subdoc having an id. The id element of the document is always the first. But in a subdoc it is not the first element.
{
"_id" : ObjectId("5848140981adc51dac264dad"),
"name" : "alpha",
"workouts" : [
{
"date" : "07-12-2016",
"timestamp" : 1481049000000,
"day_code" : 1,
"goal" : "weight_loss",
"_id" : ObjectId("5848144281adc51dac264dae"),
"workout" : [
{
"exercise_name" : "skater_hops",
"duration" : 30,
"recommended_reps" : null,
"recommended_weight" : null,
"_id" : ObjectId("5848144281adc51dac264daf"),
"details" : [ ]
}
While it makes no difference for practical purposes, it is just for ease of reading.
The schema:
var WorkoutSchema = new Schema({
date : {type : String, required : true},
timestamp : {type : Number, required : true},
day_code : {type : Number, required : true},
goal : {type : String, required : true},
workout : [WorkoutExerciseSchema]
});
var Workout = mongoose.model('Workout', WorkoutSchema, 'user');
var UserSchema = new Schema({
name : {type : String, required : true},
workouts : [WorkoutSchema]
});

Resources