The*_*KER 7 mongoose mongodb node.js mongoose-schema
下面是我的猫鼬架构
const mongoose = require('mongoose');
const AccountingCostsSchema = mongoose.Schema(
{
// other properties goes here
accountCosts: {
type: mongoose.Decimal128,
set: (v) =>
mongoose.Types.Decimal128.fromString(parseFloat(v).toFixed(4)),
required: true
}
},
{
collection: 'accountingCosts'
}
);
export = mongoose.model('AccountingCosts', AccountingCostsSchema);
Run Code Online (Sandbox Code Playgroud)
MongoDB 中的数据
会计费用收取
文本模式视图中的数据
{
"_id" : ObjectId("4e1eb38c2bdea2fb81f5e771"),
"accountId" : ObjectId("4e8c1180d85de1704ce12110"),
"accountCosts" : NumberDecimal("200.00"),
}
Run Code Online (Sandbox Code Playgroud)
文本模式视图中的数据
我的查询
db.getCollection('accountingCosts').find({'accountId': '4e8c1180d85de1704ce12110'})
Run Code Online (Sandbox Code Playgroud)
查询结果
"accountCosts": {
"$numberDecimal": "123.00"
}
Run Code Online (Sandbox Code Playgroud)
我尝试在模式上编写一个 getter 函数,就像我有一个 setter 函数一样。但它不起作用
get: function(value) {
return value.toString();
}
Run Code Online (Sandbox Code Playgroud)
我的预期输出只是一个简单的属性,其名称和值如下所示
"accountCosts": "123.00"
Run Code Online (Sandbox Code Playgroud)
MrH*_*Him 15
我确信您找到了解决方案,但我也会在这里写下来,这样谁登陆这里就能找到解决方案。您使用 a 的想法getter
是正确的,但也许您忘记在架构中启用它,所以让我们看看如何使用您的代码。
你有这个架构:
var AccountingCostsSchema = new Schema({
accountId: String,
accountCosts: {
type: Schema.Types.Decimal128,
default: 0
}
});
Run Code Online (Sandbox Code Playgroud)
因此,当您检索它时,您将得到:
{
"_id" : "12345",
"accountId" : "123456",
"accountCosts" : {
"$numberDecimal": "123.00"
}
}
Run Code Online (Sandbox Code Playgroud)
以您将得到的 accountCosts 作为数字为例,如下所示:
{
"_id" : "12345",
"accountId" : "123456",
"accountCosts" : 123
}
Run Code Online (Sandbox Code Playgroud)
正如您所说,我们需要一个getter
,所以我们需要在我们的模型文件中添加这个 getter 的函数,比如说在您的模式之后。这可能是你的 getter 函数:
function getCosts(value) {
if (typeof value !== 'undefined') {
return parseFloat(value.toString());
}
return value;
};
Run Code Online (Sandbox Code Playgroud)
现在,让我们在架构中声明这个 getter,它将变成:
var AccountingCostsSchema = new Schema({
accountId: String,
accountCosts: {
type: Schema.Types.Decimal128,
default: 0,
get: getCosts
}
});
Run Code Online (Sandbox Code Playgroud)
现在 mongoose 将了解您希望如何返回该值,但我们必须指定我们希望它使用 getter。因此,当我们想要以 json 格式检索值时,我们必须启用它。我们可以简单地添加它,如下所示:
var AccountingCostsSchema = new Schema({
accountId: String,
accountCosts: {
type: Schema.Types.Decimal128,
default: 0,
get: getCosts
}
}, {toJSON: {getters: true}});
Run Code Online (Sandbox Code Playgroud)
所以,当你检索它时,你会得到这个:
{
"_id" : "12345",
"accountId" : "123456",
"accountCosts" : 123,
"id" : "12345"
}
Run Code Online (Sandbox Code Playgroud)
但是,哇(这不是我的蝙蝠侠玻璃!)那是什么"id" : "12345"
?根据猫鼬文件:
默认情况下,Mongoose 为每个模式分配一个 id 虚拟 getter,该 getter 返回文档的 _id 字段转换为字符串,或者在 ObjectIds 的情况下,返回其十六进制字符串。如果您不希望将 id getter 添加到您的架构中,您可以通过在架构构建时传递此选项来禁用它。
我们怎样才能避免呢?我们只需添加id: false
现在的架构即可:
var AccountingCostsSchema = new Schema({
accountId: String,
accountCosts: {
type: Schema.Types.Decimal128,
default: 0,
get: getCosts
},
id: false
}, {toJSON: {getters: true}});
Run Code Online (Sandbox Code Playgroud)
现在你不会再看到它了。
最后一点提示(不,我还没有完成):如果您的模式中有一个像这样的对象数组,会发生什么?
var AccountingCostsSchema = new Schema({
accountId: String,
usersAndCosts: [{
username: String,
accountCosts: {
type: Schema.Types.Decimal128,
default: 0,
get: getCosts
}
],
id: false
}, {toJSON: {getters: true}});
Run Code Online (Sandbox Code Playgroud)
现在有坏消息:您不能继续使用此模式。现在好消息:您可以轻松修复它。您需要为其创建一个新架构usersAndCosts
,然后在父架构中引用它。让我们来看看它:
var usersAndCostsSchema = new Schema({
username: String,
accountCosts: {
type: Schema.Types.Decimal128,
default: 0,
get: getCosts
},
id: false
}, {toJSON: {getters: true}});
var AccountingCostsSchema = new Schema({
accountId: String,
usersAndCosts: [usersAndCostsSchema],
id: false
}, {toJSON: {getters: true}});
Run Code Online (Sandbox Code Playgroud)
结果是一样的,你的accountCosts
将显示为数字,没有双重 ID。请记住,这当然是为了启用 getter,toJSON
但您可能也需要启用它们toObject
,因为您可能需要对 setter 执行相同的操作。但我们在这里讨论了 JSON 的 getter。