Nodejs中怎么理解 Mongoose 的 .pre() 中间件, 还有 .path()
Nodejs中怎么理解 Mongoose 的 .pre() 中间件, 还有 .path()
官网上的例子看不懂, 这个是类似监听事件之类触发的函数么?
var schema = new Schema(..);
schema.pre('save', function (next) {
// do stuff
next();
});
var schema = new Schema(..);
schema.pre('save', true, function (next, done) {
// calling next kicks off the next middleware in parallel
next();
doAsync(done);
});
http://mongoosejs.com/docs/middleware.html
.path()
也很难懂啊:
schema.path('name') // returns a SchemaType
schema.path('name', Number) // changes the schemaType of `name` to Number
Node.js 中怎么理解 Mongoose 的 .pre()
中间件以及 .path()
1. 理解 .pre()
中间件
Mongoose 的 .pre()
方法用于定义预处理中间件。这些中间件在特定的操作(如 save
, remove
等)之前执行。你可以将它们看作是事件监听器,但更准确地说,它们是在特定操作发生前进行一些自定义逻辑处理。
示例代码:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// 定义一个简单的模式
const userSchema = new Schema({
name: String,
email: String,
password: String
});
// 在保存用户前执行的中间件
userSchema.pre('save', function(next) {
console.log('即将保存用户数据...');
// 可以在此处添加一些自定义逻辑,比如加密密码
if (this.isModified('password')) {
this.password = this.encryptPassword(this.password);
}
next(); // 调用 next() 以继续执行下一个中间件或保存操作
});
// 加密密码的方法(假设存在)
UserSchema.methods.encryptPassword = function(password) {
return '加密后的' + password;
};
// 创建模型
const User = mongoose.model('User', userSchema);
// 测试
const newUser = new User({
name: 'John Doe',
email: 'john@example.com',
password: '123456'
});
newUser.save((err) => {
if (err) console.error(err);
else console.log('用户已保存');
});
在这个示例中,当调用 newUser.save()
时,会触发 pre('save')
中间件,在保存用户数据前打印一条消息,并在密码更改时对其进行加密。
2. 理解 .path()
.path()
方法用于获取或修改指定字段的 SchemaType 对象。它通常用于访问和修改模式定义中的字段属性。
示例代码:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// 定义一个简单的模式
const userSchema = new Schema({
name: { type: String },
email: { type: String },
age: { type: Number }
});
// 获取 `name` 字段的 SchemaType 对象
const nameField = userSchema.path('name');
console.log(nameField); // 输出 SchemaType 对象信息
// 修改 `age` 字段的类型
userSchema.path('age', String);
// 打印修改后的 `age` 字段
const ageField = userSchema.path('age');
console.log(ageField); // 输出 SchemaType 对象信息,现在类型为 String
在这个示例中,我们首先定义了一个用户模式,并使用 .path('name')
获取了 name
字段的 SchemaType 对象。然后,我们通过 .path('age', String)
将 age
字段的类型从 Number
改为 String
,并再次使用 .path('age')
获取更新后的 SchemaType 对象。
通过这两个示例,你可以更好地理解 .pre()
和 .path()
在 Mongoose 中的作用和用法。
我曾经翻译过mongoose的文档,并对里面的很多例子进行了实践,虽然不多,一开始也有很多疑惑,但是使用多了,就慢慢知道什么意思了。 8.Middleware中间件 8.1 什么是中间件 中间件是一种控制函数,类似插件,能控制流程中的init、validate、save、remove方法 8.2 中间件的分类 8.2.1 Serial串行 串行使用pre方法,执行下一个方法使用next调用 var schema = new Schema(…); schema.pre(‘save’,function(next){ //做点什么 next(); }); 8.2.2 Parallel并行 并行提供更细粒度的操作 var schema = new Schema(…); schema.pre(‘save’,function(next,done){ //下一个要执行的中间件并行执行 next(); doAsync(done); }); 8.3 中间件特点 一旦定义了中间件,就会在全部中间件执行完后执行其他操作 使用中间件可以雾化模型,避免异步操作的层层迭代嵌套 8.4 使用范畴 1.复杂的验证 2.删除有主外关联的doc 3.异步默认 4.某个特定动作触发异步任务,例如触发自定义事件和通知 例如,可以用来做自定义错误处理 schema.pre(‘save’,function(next){ var err = new Eerror(‘some err’); next(err); }); entity.save(function(err){ console.log(err.message); //some err }); 不知道这看的明不明白,简单的说,中间件就相当于java中的过滤器、拦截器,在执行某个方法前,将其拦截住,也有点像AOP中的前置注入。举个简单的例子,当我们要执行save方法时,我们往往需要对存入的数据进行验证,虽然mongoose提供了safe、strict、schematype、default、validaition验证,但是这些验证都没有提供完善的错误处理或者拦截机制,而利用中间件,可以对错误的数据进行拦截、错误处理、修订等等。比如存入的用户名可能带有代码注入,这时候,通过中间件拦截用户名,给与转义,或进行错误提示、日志记录等。经过中间件的拦截,进入到save方法的数据从理想状态下应该是符合规范且完善的。由此看来,safe、strict、schematype、default、validaition本身就是内部提供的中间件。 关于path,其实也是一种中间件,如同xml的path解析,mongoose是针对mongodb数据库的一种orm模型,mongodb是javascript的json数据存储,有的时候,我们并不希望中间件只针对一个操作,而是针对操作对象的某个属性,那么就能使用path快速定位。这个类似于2.x的get和set方法,只是3.x貌似取消了。 3.x相对于2.x来说,有比较大的改进,学习的时候还得有2.x的一些基础方可。
代码没标记, 标记下吧…
类似已于MS SqlServer中的存储过程?
在存储过程里,可以对数据进行验证,如果发现错误即可选择进行回滚操作。可能中间件,就是在模仿存储过程这一思想。
pre是在执行save操作之前执行的函数,可以定义多个,并用next实现业务连接,不用next只会调用第一个。nodejs的技术欢迎加群聊262658247
呃,我发现我有理解,但是很难说出来…
就类似connect是一样的.
创建一个执行连
model.pre -> schema.pre -> schema.save
model.pre 可以是具体业务逻辑的一些数据验证,或者原始数据转换.
schema.pre 跟业务无关的数据操作
Node.js 中怎么理解 Mongoose 的 .pre()
中间件, 还有 .path()
关于 .pre()
中间件
.pre()
是 Mongoose 提供的一种中间件机制,用于在特定操作(如保存、验证等)之前执行一些自定义逻辑。它类似于事件监听器,但更具体地应用于数据库操作。
示例代码:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// 创建一个新的Schema
const userSchema = new Schema({
name: { type: String, required: true },
age: { type: Number }
});
// 在保存前执行的中间件
userSchema.pre('save', async function(next) {
console.log('即将保存用户信息');
this.age = this.age + 1; // 例如,在保存前自动给年龄加1
next(); // 继续执行后续操作
});
// 创建模型
const User = mongoose.model('User', userSchema);
// 测试代码
(async () => {
await mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true, useUnifiedTopology: true });
const newUser = new User({ name: 'John Doe', age: 25 });
await newUser.save();
})();
在这个例子中,我们在保存用户数据前会增加用户的年龄。
关于 .path()
.path()
方法允许你访问或修改指定字段的属性或类型。它返回一个 SchemaType
对象,该对象可以用来读取字段信息或进行修改。
示例代码:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// 创建一个新的Schema
const userSchema = new Schema({
name: { type: String, required: true },
age: { type: Number }
});
// 修改age字段类型
userSchema.path('age', String);
// 创建模型
const User = mongoose.model('User', userSchema);
console.log(userSchema.path('age')); // 输出修改后的SchemaType对象
// 修改后age字段的类型变为String
在这个例子中,我们通过 .path()
方法将 age
字段的类型从 Number
修改为 String
。
总结
.pre()
用于在特定操作前执行自定义逻辑。.path()
用于访问或修改指定字段的属性或类型。