Mongoose helper方法有没有findOne方法?

时间:2015-01-28 23:49:20

标签: node.js mongodb mongoose

如何添加辅助方法来查找和保存Mongoose中的对象。一位朋友告诉我使用辅助方法,但一天后我无法让他们上班。我总是收到错误,指出findOne()save()不存在或者下一个回调未定义(当节点在执行之前编译时):

我已经尝试了_schema.methods,_schema.statics ......没有用......

var email = require('email-addresses'),
    mongoose = require('mongoose'),
    strings = require('../../utilities/common/strings'),
    uuid = require('node-uuid'),
    validator = require('validator');

var _schema = new mongoose.Schema({
    _id: {
        type: String,
        trim: true,
        lowercase: true,
        default: uuid.v4
    },
    n: {                    // Name
        type: String,
        required: true,
        trim: true,
        lowercase: true,
        unique: true,
        index: true
    }
});

//_schema.index({
//    d: 1,
//    n: 1
//}, { unique: true });

_schema.pre('save', function (next) {

    if (!this.n || strings.isNullOrWhitespace(this.n)){
        self.invalidate('n', 'Domain name required but not supplied');
        return next(new Error('Domain name required but not supplied'));
    }

    var a = email.parseOneAddress('test@' + this.n);
    if (!a || !a.local || !a.domain){
        self.invalidate('n', 'Name is not valid domain name');
        return next(new Error('Name is not valid domain name'));
    }

    next();
});

_schema.statics.validateForSave = function (next) {

    if (!this.n || strings.isNullOrWhitespace(this.n)){
        return next(new Error('Domain name required but not supplied'));
    }

    var a = email.parseOneAddress('test@' + this.n);
    if (!a || !a.local || !a.domain){
        return next(new Error('Name is not valid domain name'));
    }

    next();
}

_schema.statics.findUnique = function (next) {

    this.validateForSave(function(err){
        if (err){ return next(err); }
        mongoose.model('Domain').findOne({ n: this.n }, next);
        //this.findOne({ n: this.n }, next);
    });
}

_schema.statics.init = function (next) {

    this.findUnique(function(err){
        if (err){ return next(err); }
        this.save(next);
    });
}

var _model = mongoose.model('Domain', _schema);

module.exports = _model;

2 个答案:

答案 0 :(得分:0)

我认为您因使用this而遇到问题。每次输入新函数this时,上下文都在变化。您可以在mdn了解有关this的更多信息。

此外,您的回调不允许将任何内容传递给mongoose方法。例如,如果我要创建最基本的“保存”方法,我会执行以下操作:

_schema.statics.basicCreate = function(newDocData, next) {
  new _model(newDocData).save(next);
}

现在,如果我想在Domain集合中搜索唯一文档,我将使用以下内容:

_schema.statics.basicSearch = function(uniqueName, next) {
  var query = {n: uniqueName};

  _model.findOne(query, function(err, myUniqueDoc) {
    if (err) return next(err);
    if (!myUniqueDoc) return next(new Error("No Domain with " + uniqueName + " found"));
    next(null, myNewDoc);
  });
}

答案 1 :(得分:0)

Mongoose对你正在做的事情有built in validations

_schema.path("n").validate(function(name) {
    return name.length;
}, "Domain name is required");


_schema.path("n").validate(function(name) {

    var a = email.parseOneAddress("test@" + name);
    if (!a || !a.local || !a.domain) {
        return false;
    }
    return true;
}, "Name is not a valid domain name");

返回一个布尔值。如果为false,则会使用所声明的消息将错误传递给.save()回调。为了验证唯一性:

_schema.path("n").validate(function(name, next) {

    var self = this;

    this.model("Domain").findOne({n: name}, function(err, domain) {
        if (err) return next(err);

        if (domain) {
            if (self._id === domain._id) {
                return next(true);
            }
            return next(false);
        }
        return next(true);
    });
}, "This domain is already taken");

您在此处使用self = this,以便您可以访问findOne()回调中的文档。如果名称存在,则false将被传递给回调,并且找到的结果不是文档本身。

  

我已经尝试了_schema.methods,_schema.statics

为了澄清,.statics对模型进行操作,.methods对文档进行操作。 Zane给出了一个很好的静力学例子,所以这里有一个方法的例子:

_schema.methods.isDotCom = function() {

    return (/.com/).test(this.n);
}

var org = new Domain({n: "stuff.org"});
var com = new Domain({n: "things.com"});

org.isDotCom(); // false
com.isDotCom(); // true

意见:让mongoose做验证很好,但很容易忘记它的发生。您也可能希望在应用的某个区域进行一些验证,而在其他地方使用不同的验证。除非你明确地知道你每次都必须做同样的事情而且永远不必这样做,否则我会避免使用它。

方法/静力学是一个不同的故事。每次需要检查时,调用isDotCom()而不是写出正则表达式测试非常方便。它执行一个简单的任务,为您节省一些输入并使您的代码更具可读性。使用布尔检查方法可以增加大量的可读性。定义像findByName(Zane' s basicSearch)这样的静态很有用,如果你知道你会反复进行这样的简单查询。

将Mongoose视为实用工具,而非核心功能。