What is the meaning `required` in mongoose Schema? - node.js

I am writing a mongoose schema, and I would like to understand the properties of the same.
Here is my schema:
var UserSchema = new Schema({
name: String,
username: { type: String, required: true, index: { unique: true }},
password: { type: String, required: true, select: false }
});
Why required is not declared for `name' - ?
Why required declared?
What is select - true/false -means?
When the index - should declared any why?

Why required is not declared for `name' - ?
Answer: When a field is mandatory to fill then in that case we mention it as required. So here "name" is not required or mandatory field.
Why `required' declared?
Answer: As mentioned above, When a field is mandatory to be filled then in that case we mention it as required.
What is select - true/false -means?
Answer: This means that it will not be returned by default in the data when you fetch the document. you can specify if this path should be included or excluded from query results by default.
Schema options
When the index - should declared any why?
Answer: Index should be declared when you are searching data on that field frequently so when you create indexing on that field in that case it do not search that field in all the collections it will search value for that field using index and will return result very quickly.
How indexes work in mongodb

Here, these act as model for your project. So, required is used as validation and index is working as index over that field
Now you have two ways :
either put validation over here in schemas/models
or just manually create validation for form at frontend using JS/Jquery and then long route
Now your answers:
Name is not compulsory to be filled in. That's why no required is put over there.
when there is mandatory to fill any value for that field. Then required is used in schemas.
True/False enables or disables the usage of validation over that field. If you are using false means filling in for that field isn't compulsion at all. But using false is considered a good practice.
Index is special data structure which are used for increasing performance during read/search operations. It increases the speed of operations and are stored in memory.

whenever we have to validate the particular field, so we used required.
required: true means you must fill that field.
required: false means you may or may not fill that field, but its a good practice.

Related

Is there any way to create partial index in ArangoDB?

I want to create partial index for the collection, but the index should be applied to documents by conditions. For example, I want to check uniqueness of documents only if they have the certain field value. In other words, I'm looking for some construction of index creating:
db.person.createIndex(
{ age: 1},
{ partialFilterExpression: { age: { $gte: 18 }}
);
This example is from MongoDB and it is applying index on documents with field 'age' value greater then 18
There is no way to create a "filtered index" (like you can in SQL). According to the docs, you can include attributes, but not conditionally.
You could try a sparse index, but I think your best bet is adding the age attribute to a "skiplist" index, which supports sorting and gt/lt evaluation.
Make sure you use the explain feature to validate index usage.

mongodb (mongoose) throws E11000 duplicate key error collection

I have a state model which is a lookup with just a name that i have set to unique because i don't want two states with the same name. now I have vacation model with a state property that i have set to the state schema. error E11000 duplicate key error collection is thrown after the first vacation is inserted when I insert a second vacation with the same state.I know mongodb throws the exception because I already have a vacation with the state.name as the first one.
const stateSchema = new mongoose.Schema({
name: {
type: String,
required: true,
minlength: 1,
maxlength: 30,
unique: true
}
});
const State = mongoose.model("State", stateSchema);
------------------------------------------------------
const vacationSchema = new mongoose.Schema({
-- some properties
state: {
type: stateSchema,
required: true
}
-- some properties
});
const Vacation = mongoose.model("Vacation", vacationSchema);
so how can i force unique state names in the states collection, but allow multiple vacations to have the same state in the vacations state? do I have to explicitly change state: {type: stateSchema} to {type: new Schema(...etc ?
You've two options :
If there is only one field name in State collection, also if it doesn't change(kind of nothing like rename/alter), Plus every vacation document contains only one state name then you would include state name value in state field directly in your Vacation document, this helps in if you don't want to hit other collection every time you query Vacation plus no need to maintain two collections. There is no point of directly storing names in Vacation collection if you're maintaining State collection, as there won't be any validation whether a given name exists in State collection or not, unless you do a DB call to check it before inserts to Vacation, because storing data into collections is independent - So you might need to remove unique : true from stateSchema, your code should work, as the above code is about storing data into Vacation or simply in Vacation schema make State as string & use State schema for storing data into State Collection.
Or if you really need to maintain another collection as what you've now, then you need to have a mapping between documents in State collection to documents in Vacation. This is helpful if most documents in Vacation will have multiple State names in array field. Where State names are unique in State collection. Optimal way of having relation is thru _id of State documents. If need to do that then make changes in Vacation Schema as,
state: {
type: [{ type: Schema.Types.ObjectId, ref: 'State' }],// you can make this single value instead of array.
required: true
}
After this you need to use .populate() on reads - Ref : mongoose populate
If you want to store state name as value in Vacation collection, then make state field as string, then you can use .populate() on reads - Ref : mongoose populate virtuals or similar to mongoDB's native $lookup - Ref : mongoDB $lookup
Note :
Uniqueness on State name helps when you've transactions related to State and also you need separate collection when you need to make frequent changes only on State related data + on reads as well you need only data related to State or Vacation - you make those independent as State is unique you can refer that in vacation.
Not only in mongoose schema, you also create unique index on a field, that way it will be on DB level which helps either way when running queries directly on DB or thru code, whereas mongoose schema triggers thru code, Also when you create an unique index on existing collection & runs into issue means there is already duplicate data for that field.

Why am I unable to change values of a Mongoose object to a different type ‘directly’?

I've just spent a good hour figuring out something mind-boggling (at least to me, as a JS noob) and I'd like to understand the underlying logic (or just why it works this way, because I think it's illogical and quite unexpected).
Suppose I'm using Mongoose to retrieve documents from a database, some or all of which include a date property (created with new Date()), a numeric property, and a string property.
[{
string: 'foo',
date: '2018-10-13T21:11:39.244Z',
number: 10
},
...
{
string: 'bar',
date: '2018-10-13T21:12:39.244Z',
number: 20
}]
I thus obtain an array of objects and now want to take the date property for each object and change the value to a string, so I do something like:
doc.find({}, (err, list) => {
list.forEach((item, index) => {
list[index].date = 'new value'
})
})
But I can't do that!
I can do list[index].string = 'new value' as well as list[index].date = new Date() but I can't change values that are of a different type, in this example date and number.
However, when I do list[index]._doc.date = 'new value', which took so long to figure out because I didn't know Mongoose objects weren't just plain old objects and focused on solving problems I didn't have instead, I can modify the value just fine.
It appears that the mongoose object somehow translates obj.key to obj._doc.key only if the type of the value matches but I'd appreciate a more detailed explanation than my uneducated guesses.
I suppose you want to use multi type on a document field, Mongoose support this by "Mixed" type when you define the Schema.
You can get more detail from https://mongoosejs.com/docs/schematypes.html#mixed.

Mongo index [String] property

I was just reviewing some code, and saw such property in the mongoose scheme:
names: {
type: [String],
index: true
}
As far as I understand how indexes work, they are binary trees, and how is this going to be organized as a node of a tree? Is there at all any sense of indexing such property?
'If you index a field that holds an array value, MongoDB creates separate index entries for every element of the array.' Per MongoDB documentation on multikey index.

is there a quick method to return saved data to its default value in mongoose.js

In my User Schema I have various fields with various default values. By example, see a few fields below:
acceptedStatus: {
type: String,
trim: true,
default: 'no' //possibilities (no, yes, thinkingAboutIt, yesInFuture)
}
Is there a way to quickly return the saved data for a particular field to its default value without explicitly doing it like
user.acceptedStatus = 'no';
and, if so, is there a way to return all fields that carry default values to their original status. Thanks for your help. There are times when I need to quickly do this, and didn't know if there were any methods I am missing.
One way could be that you store schema in an object, then from that object you can easily come to know what property have defaults.

Resources