如何从Node.js/Express应用程序中的Mongoose预挂钩内查询?

dor*_*emi 23 mongoose mongodb node.js express

我正在使用MongoDB w/Mongoose ORM在Node.js/Express中构建一个基本博客.

我有一个预先'保存'钩子,我想用它为我自动生成一个博客/想法slug.这工作正常,除了我要查询的部分,以查看是否有任何其他现有帖子具有相同的slug继续之前.

但是,它似乎this无法访问.find或.findOne(),所以我不断收到错误.

什么是最好的方法来解决这个问题?

  IdeaSchema.pre('save', function(next) {
    var idea = this;

    function generate_slug(text) {
      return text.toLowerCase().replace(/[^\w ]+/g,'').replace(/ +/g,'-').trim();
    };

    idea.slug = generate_slug(idea.title);

    // this has no method 'find'
    this.findOne({slug: idea.slug}, function(err, doc) {
      console.log(err);
      console.log(doc);
    });

    //console.log(idea);
    next();
  });
Run Code Online (Sandbox Code Playgroud)

Chr*_*lde 55

不幸的是,它没有很好地记录(在Document.js API文档中没有提到它),但是文档可以通过该constructor字段访问他们的模型- 我一直使用它来从插件中记录事物,这让我可以访问他们所依附的模特.

module.exports = function readonly(schema, options) {
    schema.pre('save', function(next) {
        console.log(this.constructor.modelName + " is running the pre-save hook.");

        // some other code here ...

        next();
    });
});
Run Code Online (Sandbox Code Playgroud)

根据您的情况,您应该能够:

IdeaSchema.pre('save', function(next) {
    var idea = this;

    function generate_slug(text) {
        return text.toLowerCase().replace(/[^\w ]+/g,'').replace(/ +/g,'-').trim();
    };

    idea.slug = generate_slug(idea.title);

    // this now works
    this.constructor.findOne({slug: idea.slug}, function(err, doc) {
        console.log(err);
        console.log(doc);
        next(err, doc);
    });

    //console.log(idea);
});
Run Code Online (Sandbox Code Playgroud)

  • 你究竟是怎么学到这个的?这很棒,应该明确记录...... (7认同)
  • 请注意,如果您要修改文档或根据`findOne()`的结果抛出错误或其他内容,则需要在findOne回调中移动`next()`回调. (2认同)