Node.js node/mongoose:在mongoose中间件中获取请求上下文

Node.js node/mongoose:在mongoose中间件中获取请求上下文,node.js,mongoose,Node.js,Mongoose,我正在使用mongoose(在节点上),并试图通过使用mongoose中间件向save上的模型添加一些附加字段 我正在使用一个常用的例子,希望添加一个lastmodifiedsince日期。 但是,我还想自动添加完成保存的用户的name/profilelink schema.pre('save', function (next) { this.lasteditby=req.user.name; //how to get to 'req'? this.lasteditdate = new

我正在使用mongoose(在节点上),并试图通过使用mongoose中间件向save上的模型添加一些附加字段

我正在使用一个常用的例子,希望添加一个lastmodifiedsince日期。 但是,我还想自动添加完成保存的用户的name/profilelink

schema.pre('save', function (next) {
  this.lasteditby=req.user.name; //how to get to 'req'?
  this.lasteditdate = new Date();
  next()
})
我正在使用passport--这导致req.user出现,
req
当然是http请求

谢谢

编辑


我在嵌入式模式上定义了
pre
,而在嵌入式实例的父级上调用
save
。下面发布的解决方案(将arg作为save的第一个参数传递)适用于非嵌入式case,但不适用于我的。

您可以将数据传递给您的
Model.save()
调用,然后该调用将传递给您的中间件

// in your route/controller
var item = new Item();
item.save(req, function() { /*a callback is required when passing args*/ });

// in your model
item.pre('save', function (next, req, callback) {
  console.log(req);
  next(callback);
});
不幸的是,这在今天的嵌入式模式上不起作用(请参阅)。解决方法之一是将属性附加到父级,然后在嵌入的文档中访问它:

a = new newModel;
a._saveArg = 'hack';

embedded.pre('save', function (next) {
  console.log(this.parent._saveArg);
  next();
})

如果您确实需要此功能,我建议您重新打开我上面链接的问题。

我知道这是一个非常老的问题,但我正在回答这个问题,因为我花了半天的时间试图解决这个问题。我们可以将额外属性作为选项传递,如下例所示-

findOneAndUpdate({ '_id': id }, model, { **upsert: true, new: true, customUserId: userId, ipAddress: ipaddress.clientIp** }, function (err, objPersonnel) {
在预更新中,将访问权限另存为-

schema.pre('findOneAndUpdate', function (next) {
   // this.options.customUserId,
   // this.options.ipAddress
});

谢谢,

可以通过“请求上下文”完成。要做的步骤:

安装请求上下文

npm i request-context --save
在应用程序/服务器初始化文件中:

var express = require('express'),
app = express();
//You awesome code ...
const contextService = require('request-context');
app.use(contextService.middleware('request'));
//Add the middleware 
app.all('*', function(req, res, next) {
  contextService.set('request.req', req);
  next();
})
在您的猫鼬模型中:

const contextService = require('request-context');
//Your model define
schema.pre('save', function (next) {
  req = contextService.get('request.req');
  // your awesome code
  next()
})

我应该补充一点,当我在“嵌入式父对象”上调用save时,我正在嵌入式架构上定义
pre
。您的解决方案适用于普通文档,但不适用于我描述的嵌入式案例。我更新了我的问题以反映这一点,现在我知道这很重要。无论如何,因为它回答了我不完整的问题question@Bill是否可以通过某种方式将对象/变量传递给
预验证
中间件,而不仅仅是
预保存
中间件?用例是根据当前用户的首选项传入字段的默认值(当前用户和首选项附加到my express routes中的
req
对象)。我需要在验证之前传递它们,因为这些值(即使它们是默认值)应该被验证(还有一些复杂的验证:一个字段依赖于另一个字段,等等)。保存方法呢?它在保存时工作,但在更新时上下文丢失:'(