Mongoose learning comprehension (recommended) and mongoose learning Comprehension
1. Create schemas
How to Create schemas:
var userSchema = new mongoose.Schema({ name: String, email: String, createdOn: Date });
Schemas has the following data types:
- String
- Number
- Date
- Boolean
- Buffer
- ObjectId
- Mixed
- Array
In particular, the ObjectId, Mixed, and Array types must be described. The following describes how to declare these types in schemas:
// ObjectId is similar to the unique key value projectSchema. add ({owner: mongoose. schema. types. objectId}); // mixed type, as the name suggests, that is, any type of data can be placed in it. There are two ways to create this type of data // Method 1: directly assign an empty literal object vardjSchema = new mongoose. schema ({mixedUp :{}}); // Method 2: Based on Schemas. the value of Types is used to assign vardjSchema = new mongoose. schema ({mixedUp: Schema. types. mixed}); // There are two ways to create Array data. One is to create a simple Array: var userSchema = new mongoose. schema ({name: String, emailAddresses: [String]}); // The second method is the complex data array. For example, we can add different types of schemas to the array: var emailSchema = new mongoose. schema ({email: String, verified: Boolean}); var userSchema = new mongoose. schema ({name: String, emailAddresses: [emailSchema]}); // Note: if an empty data is defined, an array of mixed data is created: var emailSchema = new mongoose. schema ({email: String, verified: Boolean}); var userSchema = new mongoose. schema ({name: String, emailAddresses: [emailSchema]});
We can create a static method for the schema. This static method will be used in the Model in the future. To create this static method, you must compile the schema after it is created:
projectSchema.statics.findByUserID = function (userid, callback) { this.find({ createdBy: userid }, '_id projectName', {sort: 'modifiedOn'}, callback); };
After the corresponding model is created and compiled, we can call the static method as follows:
Model.findByUserID(userid,callback);
This static method will return a JSON data, which is convenient when we use AJAX technology to load webpage data, as shown below:
// Routing rule: app. get ('/project/byuser/: userid', project. byUser); exports. byUser = function (req, res) {console. log ("Getting user projects"); if (req. params. userid) {Project. findByUserID (req. params. userid, function (err, projects) {if (! Err) {console. log (projects); res. json (projects);} else {console. log (err); res. json ({"status": "error", "error": "Error finding projects"}) ;}} else {console. log ("No user id supplied"); res. json ({"status": "error", "error": "No user id supplied "});}};
2. Create a Model
Creating a Model is simple:
Mongoose.Model('User', userSchema);
Parameter 1 is the name of the Model, parameter 2 is the schema required to generate the Model, and the Model is compiled as a schema.
There are two ways to connect mongoose to a database:
// Method 1: var dbURI = 'mongodb: // localhost/mydatabase'; mongoose. connect (dbURI); // Method 2: var dbURI = 'mongodb: // localhost/myadmindatabase'; var adminConnection = mongoose. createConnection (dbURI); // if you need to declare the port: var dbURI = 'mongodb: // localhost: 27018/mydatabase'; // if you need to define the user name and password: var dbURI = 'mongodb: // username: password @ localhost/mydatabase'; // You can also pass an object type parameter as follows: var dbURI = 'mongodb: // localhost/mydatabase'; var dbOptions = {'user': 'db _ username', 'pass': 'db _ password'}; mongoose. connect (dbURI, dbOptions );
Based on the method of connecting to the database, we can obtain the second method of creating the Model, that is, using the reference name of the database connection to create the Model:
adminConnection.model( 'User', userSchema );
By default, mongoose generates the collection name based on the Model name we passed in. In the code above, a collection (SET) named users (all lowercase letters) is generated );
There are two ways to customize the collection name.
// Method 1: Define the collection name when creating the schema: var userSchema = new mongoose. schema ({name: String, email: {type: String, unique: true },{ collection: 'myuserlist'}); // method 2, when creating the Model, define the collection name: mongoose. model ('user', userSchema, 'myuserlist ');
Create a Model instance:
var user = new User({ name: 'Simon' });
A user is an instance of the model User. It has some methods of the model in mongoose, such as saving the instance:
user.save(function (err) { if (err) return handleError(err); });
The model also has some common addition, deletion, query, and modification methods:
User.findOne({'name' : 'Sally', function(err,user) { if(!err){ console.log(user); }});User.find({}, function(err, users) { if(!err){ console.log(users); }});
You can use these methods in a chain, for example:
var newUser = new User({ name: 'Simon Holmes', email: 'simon@theholmesoffice.com', lastLogin : Date.now()}).save( function( err ){ if(!err){ console.log('User saved!'); }});
The above Code creates a model instance and then saves it. We have a more general method to do this, that is, using the Model. create () method:
User.create({ name: 'Simon Holmes', email: 'simon@theholmesoffice.com', lastLogin : Date.now()}, function( err, user ){ if(!err){ console.log('User saved!'); console.log('Saved user name: ' + user.name); console.log('_id of saved user: ' + user._id); }});
Iii. Methods for searching and reading data
1. Use the QueryBuilder interface to find data
Let's take a look at the following code:
var myQuery = User.find({'name' : 'Simon Holmes'});myQuery.where('age').gt(18);myQuery.sort('-lastLogin');myQuery.select('_id name email');myQuery.exec(function (err, users){ if (!err){ console.log(users); // output array of users found }});
In the code, we find the name "Simon Holmes" and the age is over 18 years old. The search results are sorted in descending order by lastLogin, and only the _ id, name, the value of the three fields in email. The code above can only really execute the database query after the exec method is called.
Of course, we can use the chained method to rewrite the above Code, and the code will be more concise:
User.find({'name' : 'Simon Holmes'}).where('age').gt(18).sort('-lastLogin').select('_id name email').exec(function (err, users){ if (!err){ console.log(users); // output array of users found }});
The first line in the above Code creates a queryBuilder. by using this queryBuilder, we can perform some complex search tasks. After the queryBuilder is created, the query operation is not executed immediately, instead, the database will be searched only when the exec method is executed.
Of course, there is another way to directly find the database, that is, to add a callback function directly in the search method. The usage is as follows:
Model.find(conditions, [fields], [options], [callback])
The following is a simple example:
User.find({'name', 'simon holmes'}, function(err, user) {});
Another complicated example:
User.find({'name', 'simon holmes'}, 'name email',function(err, user) { //console.log('some thing'); });
Another more complex example, including sorting of query results:
User. find ({'name': 'simon Holmes'}, null, // If null is used, all field values {sort: {lastLogin:-1} are returned }}, // sort functions (err, users) {if (! Err) {console. log (users );}});
List several useful search methods:
Model. find (query); Model. findOne (query); // return the first Model. findById (ObjectID) of all the queried instances; // find the unique instance based on ObjectId
For example:
User.findOne({'email' : req.body.Email}, '_id name email', function(err, user) { //todo });
2. Update Data
There are three ways to update data:
(1) update (conditions, update, options, callback );
This method will match the searched content for updates, and no data will be returned;
(2) findOneAndUpdate (conditions, update, options, callback );
This method updates the database based on the search, and returns the unchanged data;
(3) findByIdAndUpdate (conditions, update, options, callback );
This method has the same functions as the findOneAndUpdate method, but it searches for and updates documents based on the ID.
The three methods contain four parameters. The meanings of these parameters are described as follows:
- Conditions: Query conditions
- Update: The updated data object. It is an object that contains a key-value pair.
- Options: it is an option to declare the operation type. This parameter is described in detail below
- Callback: callback function
For the options parameter, the optional settings in the update method are different from those in the findOneAndUpdate and findByIdAndUpdate methods;
// In the update method, options can be set to {safe: true | false, // whether to return the error message. The default value is trueupsert: false | true, // declare whether to insert a new record if the data item to be updated cannot be queried. The default value is falsemulti: false | true, // declare whether multiple records can be updated at the same time. The default value is falsestrict: true | false // declare whether the updated data can contain field data other than the schema definition. The default value is true} // For the findOneAndUpdate and findByIdAndUpdate methods, their options can be set to {new: true | false, // declare that the returned data is before the update. If it is true, the returned data is after the update, default trueupsert: false | trure, sort: javascriptObject: string // declare the field to be returned. The value is a String}
The following is an example:
User.update({_id:user._id},{$set: {lastLogin: Date.now()}},function(){});
3. data deletion
Like updating data, there are three ways to delete data:
remove();findOneAndRemove();findByIdAndRemove();
The remove method can be used in either model or model instance. For example:
User. remove ({name:/Simon/}, function (err) {if (! Err) {// delete all users whose names contain simon}); User. findOne ({email: 'simon @ theholmesoffice.com '}, function (err, user) {if (! Err) {user. remove (function (err) {// Delete the first user matching the email address });}});
Next, let's take a look at the findOneAndRemove method:
User.findOneAndRemove({name : /Simon/},{sort : 'lastLogin', select : 'name email'},function (err, user){ if (!err) { console.log(user.name + " removed"); // Simon Holmes removed };});
Another findByIdAndRemove method is exactly the same.
User.findByIdAndRemove(req.body._id,function (err, user) { if(err){ console.log(err); return; } console.log("User deleted:", user);});
Iv. Data Verification
1. mongoose built-in data verification
In mongoose, the data verification layer is placed in the schema. mongoose has already helped us with a lot of built-in data verification. Some verification is for some data types, some of them are for all data types.
Require can be used to verify all data types, which indicates whether the field is required. For example:
email: { type: String, unique: true, required: true }
The code above defines that an email is a required schema.
Next we will introduce some built-in data verification types for mongoose.
The Number type schemasType. For data of the Number type, the value min is provided by max to define the maximum and minimum values:
var teenSchema = new Schema({ age : {type: Number, min: 13, max:19} });
The string type SchemasType. For this type of data, mongoose provides two validators:
- Match: You can use a regular expression to match the regular expression rules of a string.
- Enum: used to enumerate the values of a string.
Examples:
var weekdaySchema = new Schema({ day : {type: String, match: /^(mon|tues|wednes|thurs|fri)day$/i}});var weekdays = ['monday', 'tuesday', 'wednesday', 'thursday','friday'];var weekdaySchema = new Schema({ day : {type: String, enum: weekdays}});
When we conduct some databases, if there is an error, some error information may be returned, which is encapsulated in an object. The data format of this object is roughly as follows:
{ message: 'Validation failed', name: 'ValidationError', errors:{ email:{ message: 'Validator "required" failed for path email', name: 'ValidatorError', path: 'email', type: 'required' }, name:{ message: 'Validator "required" failed for path name', name: 'ValidatorError', path: 'name', type: 'required' } } }
After knowing the specific format of the error message, we can obtain the desired information and feed it back to the console.
if(err){ Object.keys(err.errors).forEach(function(key) { var message = err.errors[key].message; console.log('Validation error for "%s": %s', key, message); });}
2. Custom Data Verification
The simplest custom data verification method is to define a data verification function and pass it to the schema;
var lengthValidator = function(val) { if (val && val.length >= 5){ return true; } return false;};//usage:name: {type: String, required: true, validate: lengthValidator }
As you can see, we only need to add the validate key-value pair to the schema. The value of validate is our custom verification method;
However, this form of data verification cannot provide us with a complete error message. For example, the type value returned in the errors information will become undefined;
If you want to return an error description in the error message, you can make a slight modification:
//code 1validate: { validator: lengthValidator, msg: 'Too short' }//code 2var weekdaySchema = new Schema({ day : {type: String, validate: {validator:/^(mon|tues|wednes|thurs|fri)day$/i, msg: 'Not a day' }});
Modify the value of validate to an object that contains the validator and error description.
You can also write the validators in another way, that is, detach the validators from the schema, for example:
var validateLength = [lengthValidator, 'Too short' ]; var validateDay = [/^(mon|tues|wednes|thurs|fri)day$/i, 'Not a day' ]; //usage: name: {type: String, required: true, validate: validateLength } day : {type: String, validate: validateDay }
The eyes are enlarged and you can see it again. In validate, we passed in an array instead of the original object.
In fact, he is short for validateLength. You can also change it to the following:
var validateLength = [ {validator: lengthValidator, msg: 'Too short'} ];
Well, here we should be able to understand that after we change the object to an array, we can pass multiple validators to our schema, indeed.
var validateUsername = [ {validator: lengthValidator, msg: 'Too short'} , {validator: /^[a-z]+$/i, msg: 'Letters only'} ];
We also have another method to provide the validators for our schema:
userSchema.path('name').validate(lengthValidator, 'Too short');userSchema.path('name').validate(/^[a-z]+$/i, 'Letters only');
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.