How to update mongoose schema? - node.js

just started learning mongodb, currently i have this schema
var BlogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
created: {
type: Date,
default: Date.now
}});
and i wanted to update it to be like this, but currently its not working right now, when i checked it on the mongo console the schema is still the old one
var BlogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
created: {
type: Date,
default: Date.now
},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
}
});
this is the best i've come up with after reading this post, but it throw me an error TypeError: Undefined type undefined at author.required Did you try nesting Schemas? You can only nest using refs or arrays.
var BlogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
created: {
type: Date,
default: Date.now
},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: {
type: String,
required: true,
default: null
}
}
});

You can't use Schema like that instead just make another authorSchema and use it as array.
var mongoose = require('mongoose');
var authorSchema = new mongoose.Schema({
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: {
type: String,
required: true,
}
})
var BlogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
created: {
type: Date,
default: Date.now
},
author: [authorSchema]
})

Related

How to 'join' or populate an array

Here is my very basic product schema:
const productSchema = new Schema({
productName: {
type: String,
required: true,
},
productDescription: {
type: String,
},
productPrice: {
type: Number,
},
});
module.exports = mongoose.model("Product", productSchema);
These products are listed out and a user can add a quantity for each. I am storing in an array of objects as per below. I want to join these two collections together so that I can output the qty of products selected by the user. I believe I need to use populate here but not sure how to set up the Refs and so on.
const PartySchema = new Schema({
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
},
catering: [{ id: mongoose.Types.ObjectId, qty: Number }],
created_at: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("Party", PartySchema);
I'm sharing this solution with the assumption that the catering field is the sub-document array pointing to the Product Schema:
The Product Schema is fine so it stays the same (although to keep to convention I would advice naming your schema 'Products' instead of 'Product', Mongo Naming Covention):
const productSchema = new Schema({
productName: {
type: String,
required: true,
},
productDescription: {
type: String,
},
productPrice: {
type: Number,
},
});
module.exports = mongoose.model("Products", productSchema);
And next the Party Schema would be:
const PartySchema = new Schema({
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
},
catering: [{
id: {
type: mongoose.Types.ObjectId,
ref: 'Products',
},
qty: {
type: Number,
}
}],
created_at: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("Parties", PartySchema);

Is there a way to pass user Id to schema?

I have a user schema and an exam schema, i wanted to pass the id of the user to the schema of the exam
const ExamSchema = new mongoose.Schema({
-----> _id: [{
class: { type: String, required: true },
module: { type: Number,required:true },
date: {type: Date, required: true }
}]
Where it says _id - i wanted it to be the id of the user! Should i do it like this or add the exams schema on the user schema? Like this?
const UserSchema = new mongoose.Schema({
username: { type: String, require: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
active: { type: Boolean, default: true },
exam: [{
class: { type: String, required: true },
module: { type: Number,required:true },
date: {type: Date, required: true }
}]
});
Check Mongoose "Populate"
https://mongoosejs.com/docs/populate.html
A part from the docs,
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const personSchema = Schema({
_id: Schema.Types.ObjectId,
name: String,
age: Number,
stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});
const storySchema = Schema({
author: { type: Schema.Types.ObjectId, ref: 'Person' },
title: String,
fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
});
const Story = mongoose.model('Story', storySchema);
const Person = mongoose.model('Person', personSchema);
So far we've created two Models. Our Person model has its stories field set to an array of ObjectIds. The ref option is what tells Mongoose which model to use during population, in our case the Story model. All _ids we store here must be document _ids from the Story model.
In your case just make a user_id in Exam Schema and refer to id of User Schema
const ExamSchema = new mongoose.Schema({
user_id: {type: Schema.Types.ObjectId, ref: 'User' },
class: { type: String, required: true },
module: { type: Number,required:true },
date: {type: Date, required: true }
})

Using schema attributes within it's own schema? mongoose nodejs

is there a way that I could use a schema attribute within it's own model
var mongoose = require("mongoose");
//====================================================
// Schema
//====================================================
var bookSchema = new mongoose.Schema({
name: String,
image: String,
summary: String,
author: String,
genre: String,
publisher: String,
available: Number,
submitted: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User" //model name
},
username: String
},
reviews: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Review"
}
],
reserves: {
type: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Reserve"
}],
validate: [arrayLimit, '{PATH} exceeds the limit of 5']
}
});
function arrayLimit(val) {
return val.length <= 5;
}
module.exports = mongoose.model("Book", bookSchema);
in the function arraylimit. I'm trying to replace the "5" with the "available" attribute from the bookSchema.

Mongoose: Populate referenced SubDocument

I've the following schemas:
Occurence that references a competence in the CostCenter subdocuments competences.
const OccurrenceSchema = new mongoose.Schema({
date: {
type: Date,
default: Date.now,
},
competence: {
type: mongoose.Schema.Types.ObjectId,
ref: 'CostCenter.competences',
},
...
})
CostCenter where I've an array of subdocuments that can be ref by Occurence.
const CostCenterSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true,
},
competences: [CompetenceSchema],
});
And finally the Competence.
const CompetenceSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true,
},
});
When I try to populate the competence, I get "Schema hasn't been registered for model \"CostCenter.competences\".\nUse mongoose.model(name, schema)".
const occurrence_list = (request, response) => {
Occurrence.find()
.populate('occurrence origin tag entity method priority competence')
.then(occurrences => response.send(occurrences))
.catch(e => response.send(e));
};
How can I possibly populate the occurrence when referencing a subdocument?
First, you need to change your Occurrence model to this
const OccurrenceSchema = new mongoose.Schema({
date: { type: Date, default: Date.now },
competence: { type: mongoose.Schema.Types.ObjectId, ref:'CostCenter' }
});
mongoose.model('Occurrence', OccurrenceSchema);
and CostCenter model:
const CostCenterSchema = new mongoose.Schema({
name: { type: String, required: true, trim: true },
competences:[{ type: mongoose.Schema.Types.ObjectId, ref: 'Competence' }],
});
mongoose.model('CostCenter', CostCenterSchema);
finally Competence model:
const CompetenceSchema = new mongoose.Schema({
name: { type: String, required: true, trim: true }
});
mongoose.model('Competence', CompetenceSchema);
To populate the competence from Occurrence, you can do so:
Occurrence.find({ your_query })
.populate('competence')
.then(occurrences => response.send(occurrences))
.catch(e => response.send(e));
Hope it helps!

Deep population not working with embedded document

I have three documents as below:
var TrackAudioSchema = new Schema({
track_id: {
type: Number,
},
track_path:{
type:String,
required:'Please upload audio track'
}
});
mongoose.model('TrackAudio', TrackAudioSchema);
var trackSchema = new Schema({
title: {
type: String,
trim:true,
required:'Please fill track title'
},
version : {
type: String,
trim: true,
default: ''
},
trackpath:{
type: Schema.ObjectId,
ref: 'TrackAudio'
},
});
var AlbumSchema = new Schema({
language: {
type: String,
default: '',
trim: true
},
tracks:[trackSchema],
user: {
type: Schema.ObjectId,
ref: 'User'
},
)};
AlbumSchema.plugin(deepPopulate);
mongoose.model('Album', AlbumSchema);
but when I try to populate trackpath from trackSchema using the below query, it doesn't populate:
Album.findById(albumId)
.populate('user','name label').
deepPopulate('tracks.trackpath').
exec(function(err, albumdetail) {
}
Please help.
You're missing:
mongoose.model('Track', TrackSchema);

Resources