Is it possible in Mongoose, to define authorized values for a specific field ?
For example my field "style", would only be allowed to be set to "jazz", "blues" or "rock"
var artistSchema = new mongoose.Schema({
style: {
type: String
// only allow values "jazz", "blues", "rock"
}
});
First of all you are talking about mongoose schema types (String).
You have to know that it is possible to add some options when defining a schema type (options).
According to what you want to do, the option enum seems to be a good choice.
Ps: enum is a built-in validator, what is a validator?
Example from the documentation
var states = 'opening open closing closed'.split(' ')
var s = new Schema({ state: { type: String, enum: states }})
Your case
const CONSTANT_GOOD_VALUES = ['jazz', 'blues', 'rock'];
var artistSchema = new mongoose.Schema({
style: {
type: String
enum: CONSTANT_GOOD_VALUES,
},
});
Try this :-
var artistSchema = new mongoose.Schema({
status: {
type: String,
enum : ['jaz,'blues','rock']
},
});
Related
I am using mongodb with mongoose. And i am wondering if it is possible to have multiple references for an object id attribute in a schema.
I have tried the code underneath and it did not work.
const Schema = new Schema({
refrens: {
type: ObjectId,
// this did not work
ref: [
"Post",
"Account"
],
required: true
}
});
I know it is possible to remove the ref attribute (field, key) and then all object ids are valid but i want certain object ids to be valid, the object ids of the Post and Account model.
const Schema = new Schema({
refrens: {
// This will allow all different types of object ids to be the value
type: ObjectId,
required: true
}
});
Look like refPath is what you need. You can do something like this:
const Schema = new Schema({
refrens: {
type: ObjectId,
refPath: 'onModel',
required: true
},
onModel: {
type: String,
required: true,
enum: ['Post', 'Account']
}
});
I am new to mongoose and I was strugling whole day trying to understand populate. I managed to do simple examples but now I created two schemas:
First which is UserSchema with some user details:
const UserSchema: mongoose.Schema = new mongoose.Schema ({
name: String,
email: String
});
And second which is MatchSchema witch I want to be populated with user details but I am not sure if something like this will work:
const MatchSchema: mongoose.Schema = new mongoose.Schema ({
player_one: {
id: String,
score: Number,
player_details: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
},
player_two: {
id: String,
score: Number,
player_details: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
},
winner: String
},{timestamps: true});
Probably I used something which wont work and any help will be appriciated.
You need to create a Mongoose model using the UserSchema and name it 'User'. You can then create a Match model using the MatchSchema. Assuming the UserSchema and MatchSchema are in the same file, you can add the following:
const User = mongoose.model('User', UserSchema)
const Match = mongoose.model('Match', MatchSchema)
Then when you want to populate the Match model with User data:
let data = Match.find({})
.populate('player_one.player_details')
.populate('player_two.player_details')
If I have a model Attachment, which can be divided into 4 types: Link, YoutubeVideo, GoogleDriveFile, and GoogleDriveFolder, how can I use Mongoose to discriminate Attachment into these types, and allow them to be subdocuments in another schema; Post?
I've created the base Attachment model, and divided it into separate models using discriminators:
var AttachmentSchema = new Schema({
id: {type: String, required: true},
title: {type: String, required: true}
});
var Attachment = mongoose.model('Material', AttachmentSchema);
module.exports = {
DriveFile: Attachment.discriminator('GoogleDriveFile', new mongoose.Schema()),
DriveFolder: Attachment.discriminator('GoogleDriveFolder', new mongoose.Schema()),
Link: Attachment.discriminator('Link', new mongoose.Schema()),
YoutubeVideo: Attachment.discriminator('YoutubeVideo', new mongoose.Schema())
};
Now, in the Post schema, there should be an array of attachments, with varying types:
var Attachment = require('./attachment');
var PostSchema = new Schema(
text:{type: String},
attachments: [Material] // Could be Material.Link, Material.YoutubeVideo, etc
});
When I do this, I get an error saying "Undefined type Model at GoogleDriveFile. Did you try nesting Schemas? You can only nest using refs or arrays."
I don't know what this error means, and I can't find any docs explaining how to do this. Help?
Try doing the following:
var AttachmentSchema = new Schema({
id: {type: String, required: true},
title: {type: String, required: true}
});
var PostSchema = new Schema({
text: { type: String },
attachments: [ AttachmentSchema ] // Could be Material.Link, Material.YoutubeVideo, etc
});
var attachmentArray = PostSchema.path('attachments');
module.exports = {
Post: mongoose.model('Post', PostSchema),
DriveFile: attachmentArray.discriminator('GoogleDriveFile', new mongoose.Schema({})),
DriveFolder: attachmentArray.discriminator('GoogleDriveFolder', new mongoose.Schema({})),
Link: attachmentArray.discriminator('Link', new mongoose.Schema({})),
YoutubeVideo: attachmentArray.discriminator('YoutubeVideo', new mongoose.Schema({}))
};
The key is to NOT use a mongoose Model use the schema.path of the parent document schema as the base for your discriminators.
search for the term docArray on this link: Mongoose Discriminator documentation
I am using mongodb for my application and i am facing a problem like a field is accepting duplicate values as well which i dont want
I want to know how to restrict it
I have followed an approach by specifying unique :true for a field quesListName
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var QuestionListSchema = new Schema({
topicName: String,
quesList: {
quesListName: {
type: String,
unique: true
},
by: String
}
});
but still it is accepting the duplicate value
Any help is highly appreciated
You need to define the unique for the index:
var QuestionListSchema = new Schema({
topicName: String,
quesList: {
quesListName: {
type: String,
index: {
unique: true
}
},
by: String
}
});
http://mongoosejs.com/docs/api.html#schematype_SchemaType-index
How to write multi ref for one property of one mongoose schema, like this(but wrong):
var Schema = mongoose.Schema;
var PeopleSchema = new Schema({
peopleType:{
type: Schema.Types.ObjectId,
ref: ['A', 'B'] /*or 'A, B'*/
}
})
You should add string field to your model and store external model name in it, and refPath property - Mongoose Dynamic References
var Schema = mongoose.Schema;
var PeopleSchema = new Schema({
externalModelType:{
type: String
},
peopleType:{
type: Schema.Types.ObjectId,
refPath: 'externalModelType'
}
})
Now Mongoose will populate peopleType with object from corresponding model.
In the current version of Mongoose i still don't see that multi ref possible with syntax like you want. But you can use part of method "Populating across Databases" described here. We just need to move population logic to explicitly variant of population method:
var PeopleSchema = new Schema({
peopleType:{
//Just ObjectId here, without ref
type: mongoose.Schema.Types.ObjectId, required: true,
},
modelNameOfThePeopleType:{
type: mongoose.Schema.Types.String, required: true
}
})
//And after that
var People = mongoose.model('People', PeopleSchema);
People.findById(_id)
.then(function(person) {
return person.populate({ path: 'peopleType',
model: person.modelNameOfThePeopleType });
})
.then(populatedPerson) {
//Here peopleType populated
}
...