How do I set a value to be fixed aka un-updateable - mongodb

I'm making a database for beavers, however some properties should be unchangeable such as the birth date or the location where it was first seen.
How do I implement this? Is there a mongoose schema property for this? Or do I do it with JS?
Example of the schema:
let beaverSchema = new Schema({
id: {type: String, required: true, unique: true},
birthDate: {type: Date},
locationSpotted: {type: String},
firstSeen: {type: Date},
status: {type: String, default: "Alive"},
sex: {type: String}
})

Related

How to query results from multiple tables in mongoose?

I have two tables
let SalesItemsSchema = new Schema({
name: {type: String, required: true},
quantity : {type:Number , required:true},
sale_id: {type: String, required: true},
amount : {type:Number , required:true},
purchase_amount : {type:Number , required:true},
} , {timestamps : true});
let InventorySchema = new Schema({
name: {type: String, required: true, max: 100},
quantity: {type: Number, required: true},
} , {timestamps:true});
I want to get the remaining items in the inventory. For example 100 items of something were added to the inventory and 90 of them were sold.
i want to get the difference from two tables (which will be 10)
i am using mongoose.

Update field in another schema with post hook mongoose

I have that schemas:
var schema = new Schema({
number: {type: Number},
subtotal: {type: Float, required: true},
quantity: {type: Number, required: true},
prodprov: {type: Schema.Types.ObjectId, ref: 'ProdProv'},
order: {type: Schema.Types.ObjectId, ref: 'Order'}
});
module.exports = mongoose.model('OrderDetail', schema);
and
var schema = new Schema({
name: {type: String, required: true},
price: {type: Float, required: true},
idProvider: {type: Schema.Types.ObjectId, ref: 'Provider'},
idProduct: {type: Schema.Types.ObjectId, ref: 'Product'},
description: {type: String},
quantitySold: {type: Number}
});
module.exports = mongoose.model('ProdProv', schema);
I need to update field "quantitySold" when a post.save happens in order-detail, i've tried this:
schema.post('save', function(next){
//But this point I can't find the prodprov to update field
})
How I can do this?
Thank you.
Thank you #mjim, but that´s code not works. I've modify the code and works! this is my solution:
schema.post('save', function(doc){
var prod = ProdProv.findById(this.prodprov).exec().then((pp) => {
pp.quantitySold += this.quantity;
pp.save();
});
});
I would suggest:
var ProdProv = require('./ProdProv');
var schema = new Schema({
number: {type: Number},
subtotal: {type: Float, required: true},
quantity: {type: Number, required: true},
prodprov: {type: Schema.Types.ObjectId, ref: 'ProdProv'},
order: {type: Schema.Types.ObjectId, ref: 'Order'}
});
schema.post('save', async function(doc){
var prod = await ProdProv.findById(doc.prodprov);
prod.quantitySold = doc.quantity;
prod.save()
});
module.exports = mongoose.model('OrderDetail', schema);

Getting [object Object] again but doesn't seem to be model issue

I am trying to figure out how to access the author.id for a model when using a for loop with swig/twig. All of the others print out just fine but the ap.author.id is the issue I have tried ap.author.id, ap.author.id.type and ap.author.id.ref just hoping it was like my issue before seen HERE but it seems it is not model related far as I can tell. Also when I console.log out aps it shows all the documents and the path that makes sense would be ap.author.id. I am out of ideas, what am I missing?
Loop:
{% for ap in aps %}
<tr>
<td>{{ap.name}}</td>
<td>{{ap.manufacturer}}</td>
<td>{{ap.model}}</td>
<td>{{ap.type}}</td>
<td>{{ap.notes}}</td>
<td>{{ap.author.id}}</td>
</tr>
{% endfor %}
Model:
var accessPointsSchema = new Schema({
name: {type: String},
type: {type: String},
manufacturer: {type: String},
model: {type: String},
IPAdress: {type: String},
MACAdress: {type: String},
range: {type: Number()},
bands: {type: String},
channel: {type: Number},
dateBought: {type: Date},
PoE: {type: Boolean},
assetNumber: {type: Number},
warrantyExpiration: {type: Date},
location: {type: String},
notes: {type: String},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
email: String
}
});
When you console.log author.id you get back an object that will contain the ID needed but you need to access it by doing author._id otherwise you will get the [object Object] error because it is trying to output an object into a string spot.

Mongoose delete nested subdocuments and documents

I have:
let userSchema = mongoose.Schema({
email: {type: String, required: true, unique: true},
passwordHash: {type: String, required: true},
fullName: {type: String, required: true},
salt: {type: String, required: true},
ads: [{type: ObjectId, ref: 'Ad'}],
roles: [{type: String}]
}
let adSchema = mongoose.Schema({
author: {type: ObjectId, ref: 'User'},
title: {type: String, required: true},
category: {type: ObjectId, ref: 'Category', required: true},
town: {type: ObjectId, ref: 'Town', required: true},
}
);
let categorySchema = mongoose.Schema({
name: {type: String, required: true, unique: true},
ads: [{type: ObjectId, ref: 'Ad'}]
}
);
let townSchema = mongoose.Schema({
name: {type: String, required: true, unique: true},
ads: [{type: ObjectId, ref: 'Ad'}]
}
);
I want to find for example town by id and remove all ads in it(and ofcourse to remove the ads from their categories and authors).How can i do that?
I would suggest bulk getting the array of object Ids and using it like this:
Ad.remove({_id: {$in: Ad_ids_array}}, function(){...}); // and so on
You can add a pre-remove hook in the ad schema definition like this:
adSchema.pre('remove', function(next) {
let lethis = this;
// Pull ad out of all the Category docs that reference the removed ad.
this.model('Category').update({}, { $pull: {ads: lethis._id}}, { safe: true }, next);
// Pull ad out of all the User docs that reference the removed ad.
this.model('User').update({}, { $pull: {ads: lethis._id}}, { safe: true }, next);
});
This will remove the ad from the categories and users that have it in their ads array.

Modeling with MongoDB and Mongoose

I have a simple app which lists tour guides and reviews left by users about each guide. Any user can give be a guide and can give reviews. My scheme for a user is:
var User = new mongoose.Schema({
firstName: { type: String, required: true, unique: true },
lastName: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true}
isGuide: Boolean,
rating: {type: Number, "default": 0, min: 0, max: 5},
reviews: [reviewSchema]
});
var Review = new mongoose.Schema({
userId: {type: Schema.ObjectId, ref: 'User'},
author: {type: String, required: true},//contatenation of firstName and lastName of user that wrote review
rating: {type: Number, required: true, min: 0, max: 5},
reviewText: {type: String, required: true},
createdOn: {type: Date, "default": Date.now}
});
mongoose.model('User', User);
I want to be able to:
1/ show a guide and all that guide's reviews
2/ show all a user's reviews
3/ show all guides a user has reviewed
I think my schema above is fine for 1. But is it suitable for 2 and 3? Am I understanding the MonboDB philosophy correctly?