I have the following property in object defined in Mongoose schema, is there a way to prevent Moongose from assigning default enum value on App.create() or during upserting
band_collection: {
type: String,
enum: COLLECTIONS.concat('Custom')
}
// collection
COLLECTIONS = ['red', 'white', 'blue']
Hmm nope that shouldn't be happening, that code looks correct as far as I can tell. Can you provide a more complete code sample?
Related
I'm working with featherJs and mongoose.
I have a schema with an enum which I want to $inc.
new Schema({
status: { type: Number, enum: [0, 1, 2, 3], default: 0 },
});
But when I $inc the 'status' field, it doesn't care about the enum, I can $inc as many times I want and get a status to 100000.
I don't know if it's because of featherjs or something else
Thanks
This is "working as intended", as specified in the docs:
enum: Array, creates a validator that checks if the value is strictly equal to one of the values in the given array.
So enum just creates a mongoose validator, that is:
Validation is middleware. Mongoose registers validation as a pre('save') hook on every schema by default.
In theory you should be using their update validators for this, however $inc is not supported by them, and in addition their behavior is not quite clear at times.
I personally would recommend not to use mongoose at all, it's a black box that only adds bugs and confusion. specifically when it comes to their "validators" which are not "real" validators.
So what can you do to fix this?
The easiest solution is to just do it in code, first find the object and if it fits the criteria only then do the $inc, obviously this does not give actual validation and is only supported where you'd implement it, if you have many places in the code where such update can occur this is also not optimal.
use mongodb validation, this is "real" validation that actually validates at the db level. For example you could create your collection:
db.createCollection('collection_name', {
validator: {
$jsonSchema: {
bsonType: 'object',
properties: {
status: {
bsonType: 'int',
enum: [0, 1, 2, 3],
description: 'must be a valid status integer',
},
},
},
},
validationAction: 'error',
});
Now any update with a none valid value will fail.
The Mongoose docs suggest overriding the default value of [] for an array field like this:
new Schema({
toys: {
type: [ToySchema],
default: undefined
}
});
I'd like to have an array of strings, with an enum and with a default value if none is supplied.
Thus, every document has type 'foo' if none is specified, but documents may be 'foo' and 'bar'.
Is that possible?
Although the docs don't mention it, a default value can be given, in the way you'd expect.
You can have an enum array with a default value like this:
new Schema({
toys: {
type:[{ type: String, enum: ['foo', 'bar', 'baz'] }],
default: ['foo']
}
});
I defined a model as mentioned below:
var QuestionSchema = new Schema({
askedBy: {type:ObjectId, Ref:'User'},
relatedCourses: [
{type: ObjectId, ref:'Course'}
]
})
module.exports = mongoose.model('Question', QuestionSchema, 'Questions')
(Because of a bug) At the time of saving/creating new document of type Question, relatedCourses field is assigned to an array of object ids other than 'Course', and mongoose didn't produce any error, and saved the document.
It took sometime to dig and find this error.
My question is, why mongoose not checking exact Schema type? What is the need of mentioning 'Course' in ref field when any ObjectId is sufficient?
I found mongoose-id-validator, which is doing the required type validation.
I couldn't understand that for what purpose mongoose schemaType is used for. If someone could explain it will be helpful.
I'm have to reference another schema from a schema i want to know if we can get the details of all schema together when we do a findOne() on mongoose.
mixed schema means whatever you want the type to be. if you input a String, Number, Date, mongoose will let you do that. However according to documentation, mongoose ref does not work with mixed.
Note: ObjectId, Number, String, and Buffer are valid for use as refs.
if you use mixed, and ref it, you won't be able to query it back.
If you start all over(delete the database and reinsert again), use ObjectId instead of Mixed.
var storySchema = Schema({
author : { type: ObjectId, ref: 'Person' },
});
If you wish to retain old database, the best way is to change mixed to string
var storySchema = Schema({
author : { type: String, ref: 'Person' },
});
Does Mongoose support, or is there an available package that supports multiple "options" for the embedded schemas in an array?
For example, the things property can contain only one of two schemas:
new Schema({
things: [{
requiredProp: String,
otherProp: Number
}, {
otherOption: Number
}]
});
In other words, I do not want to just allow anything (AKA Schema.Types.Mixed) to be stored in this property, but only these two possible definitions.
Or, do schema design recommendations exist to avoid this problem?
You should only define one dict in the array type of the schema, and then set if they are required or not with the mongoose schema types logic. Use pre save if you want to do more logic to assure that either one of the fields have been set, like this:
var MySchema = new Schema({
things: [{
requiredProp: {type: String, required: true},
otherProp: Number,
otherOption: Number,
}]
});
MySchema.pre('save', function(next) {
if (!this.otherProp && !this.otherOption) {
next(new Error('Both otherProp and otherOption can\'t be null'))
} else {
next()
}
})
Opon saving the object it will return an error if neither otherProp nor otherOption has been set.