Node.js 添加';虚拟';mongoose模式的变量?
我有以下文档架构:Node.js 添加';虚拟';mongoose模式的变量?,node.js,mongoose,Node.js,Mongoose,我有以下文档架构: var pageSchema = new Schema({ name: String , desc: String , url: String }) 现在,在我的应用程序中,我还希望在对象中包含页面的html源代码,但我不希望将其存储在db中 我应该创建一个引用db文档的“本地”增强对象吗 function Page (docModel, html) { this._docModel = docModel this._html =
var pageSchema = new Schema({
name: String
, desc: String
, url: String
})
现在,在我的应用程序中,我还希望在对象中包含页面的html源代码,但我不希望将其存储在db中
我应该创建一个引用db文档的“本地”增强对象吗
function Page (docModel, html) {
this._docModel = docModel
this._html = html
}
有没有办法通过添加“虚拟”字段直接使用文档模型?这在mongoose中是完全可能的。
从他们的文档中选取以下示例:
var personSchema = new Schema({
name: {
first: String,
last: String
}
});
personSchema.virtual('name.full').get(function () {
return this.name.first + ' ' + this.name.last;
});
console.log('%s is insane', bad.name.full); // Walter White is insane
在上面的示例中,属性没有setter。要为此虚拟机设置setter,请执行以下操作:
personSchema.virtual('name.full').get(function () {
return this.name.full;
}).set(function(name) {
var split = name.split(' ');
this.name.first = split[0];
this.name.last = split[1];
});
我还没有实际测试过这一点,但这个想法似乎很有价值:
//model
var pageSchema = new Schema({
name: String
, desc: String
, url: String
})
pageSchema.virtual('html')
.get(function(){
var url = this.url
function get(url) {
return new (require('httpclient').HttpClient)({
method: 'GET',
url: url
}).finish().body.read().decodeToString();
}
return get(url);
});
//controller
var page = new Page({
name: "Google"
, desc: "Search engine"
, url: "http://google.com"
});
var html = page.html;
基本上设置一个名为html
的虚拟属性,该属性请求url
属性的主体并返回它
如果您正在使用express和res.send(page)
,请确保为toJSON启用虚拟属性的输出
以
开头的文档属性不会持久化到数据库中,因此您可以创建一个虚拟属性,并让getter和setter使用。\uu html
pageSchema.virtual('html').get(function () {
return this.__html;
}).set(function (html) {
this.__html = html;
});
但这有点像黑客攻击,但有一点需要注意:此功能没有文档记录,因此没有以\uuuu
开头的内部属性列表,因此有可能(尽管可能性不大)在将来内部实现可以开始使用名为\uuu html
的变量
pageSchema.virtual('html').get(function () {
return this.__html;
}).set(function (html) {
this.__html = html;
});
2020年
可以通过在模型中添加以下对象字段来设置虚拟对象
toJSON: { virtuals: true },
toObject: { virtuals: true }
上面的例子和下面的例子是等价的,但上面的例子简短而简单
itemSchema.set('toJSON', {
virtuals: true
});
这是一个例子
型号
const itemsSchema = new mongoose.Schema({
image: {
type: String,
trim: true,
required: [true, 'Please provide item image']
},
color: {
type: String,
trim: true
},
size: {
type: String,
trim: true
},
price: {
type: Number,
required: [true, 'Please provide item price']
},
shipping: {
type: Number
},
discount: {
type: Number
},
details: {
type: String,
trim: true
}
}, {
toJSON: { virtuals: true },
toObject: { virtuals: true }
});
设置虚拟模式
itemsSchema.virtual('totalPrice').get(function() {
const sub_total = this.price + this.shipping;
return (sub_total - ( ( sub_total / 100 ) * this.discount )).toFixed(2)
});
为什么要将它放在对象中而不是存储它?因为我不需要它是持久的:如果我重新启动服务器并从数据库中重新加载对象,html也需要更新(它来自外部进程)。我可以储存它,但这会浪费空间。因为在Mongoose中有虚拟方法,所以最好也有虚拟变量。您只需在对象上设置一个属性,如document.prop=html
。我认为,如果您再次从数据库中获取对象,即使不重新启动,该方法或virtuals实际上也不会让您获取“本地”数据。哦,对了。我可以简单地添加一个新属性。让我困惑的是,如果我做了page.newProperty=“something”;console.log(page)
它不会在输出中显示newProperty
。。但是如果我做了console.log(page.newProperty)
我会看到值:|不要这样做。检查我的答案,mongoose支持虚拟现实。是的,但他们没有添加新字段。。他们正在使用现有的。问题是什么?你也可以使用setter。哦,我明白了。你的意思是我应该this.newfield=
在虚拟set
中。但我不确定这是否有任何意义:lI必须在模式选项中为“toObject”和“toJSON”激活虚拟体。否则我就不行了。在这里: