如何添加辅助方法来查找和保存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;
答案 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视为实用工具,而非核心功能。