Nodejs中怎么理解 Mongoose 的 .pre() 中间件, 还有 .path()

发布于 1周前 作者 phonegap100 来自 nodejs/Nestjs

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

7 回复

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() 用于访问或修改指定字段的属性或类型。
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!