[求助] Nodejs Mongoose 数据类型的问题
[求助] Nodejs Mongoose 数据类型的问题
在mongoose中定义以下Schema:
var v = new Schema({
name: { type: String },
status: { type: Number }
});
然后在查询结果中想将Number类型的status字段替换成字符串返回:
model.find(function(datas) {
datas.forEach(function(n){
switch(n.status) {
case 1: n.status = "正常"; break;
case 2: n.status = "不正常"; break;
default: n.status = "未知"; break;
}
})
res.render("a", {data:datas});
});
但是,由于model里面定义的status字段类型是Number,所以导致这里遍历结果集修改字段为字符串不生效。
请教下这里应该怎么处理啊(PS:排除在view中进行处理的方法)
在Mongoose中,如果你希望在查询结果中将status
字段从数字转换为字符串,可以通过使用虚拟属性(virtuals)或者自定义getter来实现。下面是两种方法的示例:
方法一:使用虚拟属性(Virtuals)
虚拟属性允许你在模型中定义一个属性,但不会存储到数据库中。你可以通过这种方式定义一个名为statusStr
的新属性,它会根据status
字段的值动态生成。
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var schema = new Schema({
name: { type: String },
status: { type: Number }
});
// 定义虚拟属性
schema.virtual('statusStr')
.get(function() {
switch(this.status) {
case 1: return "正常";
case 2: return "不正常";
default: return "未知";
}
});
var model = mongoose.model('MyModel', schema);
model.find({}, function(err, datas) {
if (err) {
console.error(err);
return res.status(500).send("Error fetching data");
}
// 将数据渲染到视图
res.render("a", { data: datas });
});
方法二:使用自定义getter
你也可以直接在模型上添加一个getter方法,这样当你访问status
属性时,它会自动调用这个getter方法并返回对应的字符串。
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var schema = new Schema({
name: { type: String },
status: { type: Number }
});
// 添加getter
schema.path('status').get(function(statusNum) {
switch(statusNum) {
case 1: return "正常";
case 2: return "不正常";
default: return "未知";
}
});
var model = mongoose.model('MyModel', schema);
model.find({}, function(err, datas) {
if (err) {
console.error(err);
return res.status(500).send("Error fetching data");
}
// 将数据渲染到视图
res.render("a", { data: datas });
});
这两种方法都可以实现将status
字段从数字转换为字符串的目的,并且不需要在视图层进行额外处理。选择哪种方法取决于你的具体需求和个人偏好。
推荐你使用mongoose的Virtuals属性,参见http://mongoosejs.com/docs/guide.html
这是个localization的问题,确实是放在view中处理比较合理 此外,mongoose对String提供enum支持:
var v = new Schema({
name: { type: String },
status: { type: String, enum: ['normal', 'abnormal', 'unknown'] }
});
你这里修改status不成功原因是mongoose的查询返回的是mongoose的document对象,不要当成POJO处理,这是个大坑,一定要记住,很多莫名其妙的错误都来源于此
document可以用toObject
转换成POJO对象
model.find(function(datas) {
datas.forEach(function(n, index){
n = n.toObject();
switch(n.status) {
case 1: n.status = "正常"; break;
case 2: n.status = "不正常"; break;
default: n.status = "未知"; break;
}
datas[index] = n;
})
res.render("a", {data:datas});
});
我尝试将结果集遍历重新赋值给另一个遍历,结果还是不行,我想到可能是由于mongoose返回的原因。 但是有点想不通的是,对于Javascript来说,应该就是Object类型,我通过输出发现结果接只是单纯的查询结果,如果是特殊的类型应该返回的是包含有一坨坨自定义原型的结构吧。
在Mongoose中,你可以使用virtuals
来定义一个虚拟属性,这样可以在不影响数据库存储的情况下对数据进行转换。虚拟属性不会被保存到数据库中,但可以在查询结果中动态生成。
你可以通过添加一个虚拟属性来实现将 status
字段从数字转换为字符串。以下是具体步骤:
- 定义虚拟属性。
- 在虚拟属性上设置
get
方法来返回转换后的值。
以下是示例代码:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// 定义Schema
var v = new Schema({
name: { type: String },
status: { type: Number }
});
// 添加虚拟属性statusStr
v.virtual('statusStr')
.get(function() {
switch(this.status) {
case 1: return "正常";
case 2: return "不正常";
default: return "未知";
}
});
// 创建Model
var Model = mongoose.model('Model', v);
// 查询并渲染
Model.find()
.then((datas) => {
res.render("a", { data: datas });
})
.catch((err) => {
console.error(err);
});
在这个示例中,我们添加了一个名为 statusStr
的虚拟属性,并在其 get
方法中根据 status
字段的值返回相应的字符串。这样,在查询结果中可以通过 statusStr
获取到转换后的字符串,而无需在循环中手动修改 status
字段。
这样处理后,你在视图中可以直接使用 statusStr
属性来显示状态信息。