When does mongoose schema update its keys? - javascript

I originally had this mongoose schema:
const scriptsSchema = mongoose.Schema({
title: {
type: String,
require: true
},
updated: {
type: Date,
default: Date.now(),
require: true
}
});
export default mongoose.models.Script || mongoose.model('Script', scriptsSchema)
That i updated to
const constructDate = () => {
var today = new Date();
return (today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate())
}
const scriptsSchema = mongoose.Schema({
title: {
type: String,
require: true
},
updated: {
type: Date,
default: constructDate(),
require: true
}
});
export default mongoose.models.Script || mongoose.model('Script', scriptsSchema)
Since I wanted to have only the date (no time) as a default value in the 'updated' field. Problem is, the change does not reflect and whenever I create a new script document, the default 'updated' value is still Date.now().
I tried dropping the collection, resetting the database... but somehow it doesen't notice the changes I've made in the schema.
My problem is not about updating the existing documents, since I am still in developement phase and I don't mind dropping all documents in the database. I just want the schema to update to its new version.

Related

can't update boolean mongoose object with a time stamp

I am having trouble updating a boolean object and i am getting error every time-
this is the object-
const mongoose = require('mongoose');
const PlantProductSchema = new mongoose.Schema({
waterMotor: {
state: {
type: Boolean,
default: false,
time: { type: Date, default: Date.now },
}
},
});
module.exports = mongoose.model('PlantProduct', PlantProductSchema);
this is the update action-
plantProduct.waterMotor.update({state: idResultsObj.motorState });
idResultsObj.motorStat is boolean i chacked
on the other hand when I change I do this -
plantProduct.waterMotor.state = idResultsObj.motorState;
it works but It doesn't give a time stamp.
I appreciate any help I get!!
you are not using the update function correctly. it accepts two arguments, the first is the document to be updated and the second is the action.
you need to pass the id (or any other field like username) of the document that is being updated as the first argument.
plantProduct.waterMotor.update({_id: id}, {state: idResultsObj.motorState });
These are a couple of API which mongoose support for an update operation.
Regarding your code you have used update in the wrong way. update is the property of the Model object that why you are getting undefined. thought said below is the query that might help you.
const mongoose = require('mongoose');
const PlantProductSchema = new mongoose.Schema({
waterMotor: {
state: {
type: Boolean,
default: false,
time: {
type: Date,
default: Date.now
},
}
},
});
const ProductModel = mongoose.model('PlantProduct', PlantProductSchema);
const filterQuery = {}
const updateQuery = {
$set: {
"waterMotor.state": true
}
}
ProductModel.update(filterQuery, updateQuery, function(error, result) {
if (error) {
console.log(error)
} else {
console.log(response)
}
})

Enforcing the default value in Mongoose schema

I have been trying to find a way to enforce the default value of a schema so that the default value is being used upon insert regardless of any input parameter. In other words a property of a schema should always have the default value and if any other parameter is being passed on insert/write that passed parameter would be ignored.
As an example, please see my dummy schema below. The property I want to enforce is MySchema.created, which is supposed to store the timestamp of the moment document gets created.
var mongoose = require("mongoose");
var MySchema = new mongoose.Schema({
sendStatus: {
type: String,
enum: ["notsent", "sent", "failed"],
default: "notsent"
},
created: {
type: Date,
default: Date.now
},
creator: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true
}
});
I did not find an answer in Mongoose documentation (http://mongoosejs.com/docs/defaults.html) even though it do mention setDefaultsOnInsert, which sounds somewhat close. Altough I would like to do all the schema validation and enforcements on schema level to avoid development mistakes and copy-paste code. Also I don't see how I could use setDefaultsOnInsert for this timestamp, because I want to keep it also constant and not update it upon document update.
Is this possible to achieve? Having a reliable creation date on a document must be a very common use case, but somehow I fail to find a satisfying answer in the internet. Thanks!
You can simply add Mongoose timestamps to the end of your schema and it will timestamp your new/updated document
var MySchema = new mongoose.Schema({
sendStatus: {
type: String,
enum: ["notsent", "sent", "failed"],
default: "notsent"
},
creator: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true
}
},{
timestamps:
{
createdAt: 'created_at',
updatedAt: 'updated_at' //leave this out if of no interest
}
});

Does order of schema matter in Node.JS?

Im about to make a huge schema for a form that I have just built... that being said does my schema order have to mimic the form order, or can it just have all the inputs in any order I put them in ?
Example below.
can it be like this?
// link to mongoose
var mongoose = require('mongoose');
// define the article schema
var mapSchema = new mongoose.Schema({
created: {
type: Date,
default: Date.now
},
dd1: {
type: String,
default: ''
},
dd2: {
type: String,
default: ''
},
com1: {
type: String,
default: ''
},
com2: {
type: String,
default: ''
}
});
// make it public
module.exports = mongoose.model('Map', mapSchema);
Or does it have to be like this?
// link to mongoose
var mongoose = require('mongoose');
// define the article schema
var mapSchema = new mongoose.Schema({
created: {
type: Date,
default: Date.now
},
dd1: {
type: String,
default: ''
},
com1: {
type: String,
default: ''
},
dd2: {
type: String,
default: ''
},
com2: {
type: String,
default: ''
}
});
// make it public
module.exports = mongoose.model('Map', mapSchema);
does my schema order have to mimic the form order, or can it just have all the inputs in any order I put them in?
mongoose.Schema accepts a JavaScript object as its parameter. So your question boils down to:
Are JavaScript objects aware of the order their keys were defined in?
The answer to that is: No, key order is not maintained in JavaScript objects. The JS spec explicitly states that objects are unordered key/value collections. (compare)
Therefore it follows that mongoose.Schema could not rely on key order even if it tied to, which means you are free to order the keys in any way you like.
We can also tackle the question from the other end:
Is it likely that a front-end change like form field order forces me to rewrite my database backend code?
And the answer to that is: No, that is pretty darn unlikely. We can dismiss that thought without even looking into any kind of spec, because it would not make any kind of sense.

Mongoose/MongoDb ,how to validate an array of Ids against another model

I have 2 moongose Schema:
var Schema2 = new Schema({
creator : { type: String, ref: 'User'},
schema_name : [{ type: String}],
});
var Schema1 = new Schema({
creator : { type: String, ref: 'User'},
schema_ref : [{ type: String, ref: 'Schema2' }],
});
Would like to know which is the best practice when I create a new Schema1 check that every element of array schema_ref, have the same creator.
Because schema1 elements are added by client form and so i have to check that the schema_ref elements are owned by same User that send the form
You can try with either validator function, or with a simple 'save' middleware:
Schema1.pre('save', function(next) {
let owner;
for (let entry in this.schema_ref) {
if (!owner) {
owner = entry;
} else {
if (entry !== owner) {
return next(new Error("owner mismatch");
}
}
}
});
Also, your schema might not work as you expect it to, it looks like you actually need:
schema_ref: [{
type: {type: String},
ref: "User"
}]
Additionally, take a look at id-validator plugin, or some similar to that - it will, in addition to your validation, also check that all ref-type properties like this actually exist in the other (Users) collection.

How to add some action after document update in mongoose

E.g. I have field lastModified and when object is modified this field should be updated with current date. How can I do this with mongoose.js?
Schema example:
var schema = new Schema({
someFieldForUpdates: {
type: String,
},
//when 1st field changed this one should be updated too
lastModified: {
type: Date,
default: Date.now()
}
});
I think it could be done with middlewares like post-save or pre-save maybe
http://mongoosejs.com/docs/middleware.html
schema.post('save', function (doc) {
console.log('%s has been saved', doc._id);
// update another field
})

Categories

Resources