I would like to define a Mongoose Schema which accepts any property name in connection with a String as its value. What I am looking for is something like the following (Without having first to write any possible property name):
var schema = new Schema({
name: String,
someStrings: {
string1: String,
string2: String,
...
stringN: String
}
});
I know I could simply use Schema.Types.Mixed, but that would make it possible to use arrays or other types inside. Furthermore would Mongoose lose the ability to auto detect and save changes on this property.
var schema = new Schema({
name: String,
someStrings: Schema.Types.Mixed
});
I just want to have an Object (someString), which only consists of an arbitrary count of name to value String mappings with any name possible.
Is something like this even possible in mongoose?
var schema = new Schema({
name: String,
strings: {
type: Object,
default: {
string1: String,
string2: String,
...
stringN: String
}
}
});
Related
i want to define the schema dynamically according to the condition using mongoose
Schema
new mongoose.Schema({
type: String, //BASIC OR ADVANCE
// only for type = BASIC
name: String,
age: Number
/*
want these fields too but only if type = ADVANCE
email: String,
password: Number
PhoneNumber: String
*/
});
how would i achieve this kind of schema using mongoose.
it depends on what your approach to your database is. you can simply create two types with identifiers as Advance and Basic and use middleware to maintain the flow. Now to answer your question:
something like:
new mongoose.Schema({
type: String, //BASIC OR ADVANCE
// only for type = BASIC
name: String,
age: Number,
advance: []
And now you can check if advance is empty or not. Seriously it all depends on your approach, how you deal with the problem. Once a Schema is declared you can without the advance field, you can still save data like:
const MyModel = mongoose.model('Test', new Schema({ name: String }));
const doc = new MyModel();
doc.advance = {
email: "test#test.com",
password: 1234,
PhoneNumber: 1234
}
doc.save();
But with this structure if you want to know the Schema, you'll think that in your file it is only name and age and later when you start exploring, you'll find out that you are doing something like this and using a proper structure.
Think of moongoose documents as JavaScript Objects, there is a reason it is known as non-Structured data. Hope this explanation helps.
The enum validation works when it's a single String:
var songSchema = new Schema({
vocalRange: {
type: String,
enum: ["Soprano", "Mezzo-soprano", "Contralto", "Alto", "Tenor", "Baritone", "Bass"],
}
})
Trying to POST anything but what's in the enum returns a validation error through mongoose.
However, the following:
var songSchema = new Schema({
vocalRange: {
type: [String], // this is what changed
enum: ["Soprano", "Mezzo-soprano", "Contralto", "Alto", "Tenor", "Baritone", "Bass"],
}
})
Allows me to POST anything for vocalRange without any kind of validation. What's going on? And why doesn't the validation work for an array of strings like it does for a single string?
Answering from my comment:
vocalRange: [{ type: String }]
should work.
As of mongoose version 5.0.6 and higher, the OP issue now works!
vocalRange: {
type: [String], // this now works!
enum: ["Soprano", "Mezzo-soprano", "Contralto", "Alto", "Tenor", "Baritone", "Bass"],
}
Reference
https://github.com/Automattic/mongoose/issues/6204#issuecomment-374690551
Is there a way for checking if a reference document id exists in the array field of its "parent" model?
Imagine you know the objectId you want to check if exists because you don't want duplicates and also want to avoid that an error was thrown when trying to insert it.
I would like to know if there is an elegant and simple way as the method mongoose provides when working with subdocuments: var doc = car._components.id(theComponentIdIWantToCheck)
In this case it is a reference document:
Example:
// Car.js
var CarSchema = new Schema({
name: String,
description: String,
_components: [ { type: Schema.Types.ObjectId, ref: 'Component'},]
});
I have a mongo object and wish to access it via mongoose for my web app. The schema I've defined has an Object storing user ids and a 3-level value (yes, maybe or no).
e.g.
"user_info": {
"<id_value_1>": "y",
"<id_value_2>": "n"
}
The id_value_*s above are the users session ids so a long string of random characters. How can I create a mongoose Schema for this?
Would user_info: {String, String} work?
I could restructure it so that the user_info is an array of objects { "sessionid": "<value>", "value: "y"}, which would be ok, is this the best option?
You'll be better off if you avoid dynamic keys in your schema and go with your second idea of:
user_info: [{sessionid: String, value: String}]
You can use the $ positional operator to update individual user_info array elements by sessionid.
You may try with Schema Type Mixed like this way
var user = new Schema({
info: [Schema.Types.Mixed]
});
user.info = { any: { thing: 'i want' } };
user.markModified('info');
You can read more about it here
After testing the above, I found that defining the schema as user_info: { String: String } is a valid way to do this (option 1 specified in the question).
You may define objects and arrays in your schema. You may even combine them. For example, this is an array of objects:
var user = new Schema({
foo: [ {
address: {type: String},
email: {type: String, unique: true}
}],
bar: [ "simple", "array" ]
});
I would like to have a nested object in the detail for the activiy log. See the example. How do I define the schema in mongoose?
activity: {
date: '1/1/2012' ,
user: 'benbittly',
action: 'newIdea',
detail: {
'title': 'how to nest'
, 'url': '/path/to/idea'
}
activity: {
date: '1/2/2012' ,
user: 'susyq',
action: 'editProfile',
detail: {
'displayName': 'Susan Q'
, 'profileImageSize': '32'
, 'profileImage': '/path/to/image'
}
Use the Mixed type, which allows you to store the arbitrary sub-objects in your example.
var Activity = new Schema({
date : Date
, user : String
, action : String
, detail : Mixed
})
To indicate an arbitrary object (i.e. "anything goes") in your schema you can use the Mixed type or simply {}.
var activity: new Schema({
date: Date,
user: String,
action: String,
detail: Schema.Types.Mixed,
meta: {} // equivalent to Schema.Types.Mixed
});
The catch
For the added flexibility there is a catch, however. When using Mixed (or {}), you will need to explicitly tell mongoose that you have made changes like so:
activity.detail.title = "title";
activity.markModified('detail');
activity.save();
Source
Mongoose docs