如何从预钩子中检索文档的属性?

时间:2018-12-21 16:45:20

标签: node.js mongodb mongoose

我昨天发布了这个问题,因为我不知道如何解决我的问题。

Change variable value in document after some time passes?

有人告诉我我需要使用预钩子。我尝试这样做,但是“ this”将引用查询,而不是文档。因此,我无法检索文档来检查4个星期是否过去了。 (检查问题,您会得到的)

因为我不知道如何使此.pre('find')使用每个文档中的变量(因此它检查是否经过了4周),所以我想遍历所有变量并检查是否4个星期过去了。

router.get('/judet/:id([0-9]{2})', middleware.access2, function(req, res)
{
      var title = "Dashboard";
      Somer.find({}, function(err, someri)
      {
        if(err)
        {
            console.log(err);
        }
        else
        {
            res.render("dashboard", {title: title, id:req.params.id, someri:someri});
        }
      });
}); ///get route
var someriSchema = new mongoose.Schema({
    nume: {type: String, required: true},
    dateOfIntroduction: {type:Date, default: Date.now, get: formatareData},
});

someriSchema.pre('find', function(next) {
    console.log(this.dateOfIntroduction); <- this will return undefined, because this refers to the query, actually
    next();
});///schema and the pre hook. I thought I could use it like this, and inside the body of the pre hook I can check for the date

这就是我在说的:

router.get('/judet/:id([0-9]{2})', middleware.access2, function(req, res)
{
      var title = "Dashboard | Best DAVNIC73";
      Somer.find({}, function(err, someri)
      {
        if(err)
        {
            console.log(err);
        }
        else
        {
            someri.forEach(function(somer)
            {
            ///check if 4 weeks passed and then update the deactivate variable
            })
            res.render("dashboard", {title: title, id:req.params.id, someri:someri});
        }
      });
});

但是我认为如果在数据库中获得很多条目,这将是非常糟糕的性能,而且我认为这不是实现此目的的最佳方法。

因此,如果我被正确告知,并且我应该使用前置钩子来获取我所说的话,那么如何使它引用文档?

2 个答案:

答案 0 :(得分:1)

好的,我想我了解您的要求。这是您可以做的:

/*
  this will always set a documents `statusFlag` to false, if the 
  `dateOfIntroduction` was before Date.now()
*/
const mongoose = require('mongoose')
someriSchema.pre('find', function(next) {
  mongoose.models.Somer.update(
   { datofIntroduction: { $lte: new Date() }}, 
   { statusFlag : false})
   .exec()
   .then((err, result) => {
     // handle err and result
     next();
   }); 
});

我看到的唯一问题是,您在每次查找时都发出此请求。

答案 1 :(得分:-1)

  

在查询中间件中,猫鼬不一定具有对   正在更新的文档,所以这是指查询对象,而不是   比正在更新的文档。

直接取自mongoose的文档

我昨天向您指出了他们的文档;但这是一个更具体的答案。

someriSchema.post('find', function(res) {
  // res will have all documents that were found
  if (res.length > 0) {
    res.forEach(function(someri){
        // Do your logic of checking if 4 weeks have passed then do the following
        someri.deactivated = true
        someri.save()
    })
  }
})

这基本上是针对每个找到的模式进行相应更新的属性,如果仅查询1个对象,则res只能有1个对象。您的第二个解决方案是执行cron

编辑:这是解决异步问题的方法

const async = require('async')

someriSchema.post('find', function(res) {
  async.forEach(res, function(someri, callback) {
       // Do your logic of checking if 4 weeks have passed 
       // then do the following - or even better check if Date.now() 
       // is equal to expiryDate if created in the model as suggested
       // by `BenSow`

       // Then ONLY if the expiry is true do the following
       someri.deactivated = true
       someri.save(function (err) {
            err ? callback(err) : callback(null)
       })
  }, function(err){
     err ? console.log(err) : console.log('Loop Completed')
  })
})