Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js mongoDB在查询响应中返回$numberdCimal_Node.js_Mongodb_Mongoose_Mongoose Schema - Fatal编程技术网

Node.js mongoDB在查询响应中返回$numberdCimal

Node.js mongoDB在查询响应中返回$numberdCimal,node.js,mongodb,mongoose,mongoose-schema,Node.js,Mongodb,Mongoose,Mongoose Schema,下面是我的猫鼬模式 const mongoose = require('mongoose'); const AccountingCostsSchema = mongoose.Schema( { // other properties goes here accountCosts: { type: mongoose.Decimal128, set: (v) => mongoose

下面是我的猫鼬模式

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);
MongoDB中的数据

会计成本收集

文本模式视图中的数据

{
    "_id" : ObjectId("4e1eb38c2bdea2fb81f5e771"),
    "accountId" : ObjectId("4e8c1180d85de1704ce12110"),
    "accountCosts" : NumberDecimal("200.00"),
}
"accountCosts": "123.00"
文本模式视图中的数据

我的查询

db.getCollection('accountingCosts').find({'accountId': '4e8c1180d85de1704ce12110'})
"accountCosts": {
      "$numberDecimal": "123.00"
}
查询结果

db.getCollection('accountingCosts').find({'accountId': '4e8c1180d85de1704ce12110'})
"accountCosts": {
      "$numberDecimal": "123.00"
}
我尝试在模式上编写getter函数,就像编写setter函数一样。但它不起作用

get: function(value) {
      return value.toString();
}
我的预期输出只是一个普通属性,其名称和值如下所示

{
    "_id" : ObjectId("4e1eb38c2bdea2fb81f5e771"),
    "accountId" : ObjectId("4e8c1180d85de1704ce12110"),
    "accountCosts" : NumberDecimal("200.00"),
}
"accountCosts": "123.00"

我相信你找到了一个解决方案,但我也会把它写在这里,这样谁会在这里着陆,谁就会找到一个解决方案。 您使用
getter
的想法是正确的,但是可能您忘记了在模式中启用它,所以让我们看看如何使用您的代码

您有以下架构:

var AccountingCostsSchema = new Schema({
    accountId: String,
    accountCosts: {
        type: Schema.Types.Decimal128,
        default: 0
    }
});
因此,当您检索它时,您将得到:

{
    "_id" : "12345",
    "accountId" : "123456",
    "accountCosts" : {
        "$numberDecimal": "123.00"
    }
}
例如,您可以将accountCosts作为数字,如下所示:

{
    "_id" : "12345",
    "accountId" : "123456",
    "accountCosts" : 123
}
正如您所说,我们需要一个
getter
,因此我们需要在模型文件中添加这个getter的函数,比如在您的模式之后。这可能是您的getter函数:

function getCosts(value) {
    if (typeof value !== 'undefined') {
       return parseFloat(value.toString());
    }
    return value;
};
现在,让我们在模式中声明这个getter,它将成为:

var AccountingCostsSchema = new Schema({
    accountId: String,
    accountCosts: {
        type: Schema.Types.Decimal128,
        default: 0,
        get: getCosts
    }
});
现在mongoose将了解如何返回该值,但我们必须指定希望它使用getter。因此,当我们想要以json格式重设值时,必须启用它。我们可以简单地添加如下内容:

var AccountingCostsSchema = new Schema({
    accountId: String,
    accountCosts: {
        type: Schema.Types.Decimal128,
        default: 0,
        get: getCosts
    }
}, {toJSON: {getters: true}});
因此,当您检索它时,您将得到:

{
    "_id" : "12345",
    "accountId" : "123456",
    "accountCosts" : 123,
    "id" : "12345"
}
但是,哇(这不是我的蝙蝠侠眼镜!)那是什么
“id”:“12345”
? 根据:

默认情况下,Mongoose为每个模式分配一个id虚拟getter,该getter将文档的_id字段强制转换为字符串,如果是ObjectID,则返回其hexString。如果不希望将id获取程序添加到模式中,可以通过在模式构建时传递此选项来禁用它

我们如何避免它?我们可以在我们的模式中添加
id:false
,现在将是:

var AccountingCostsSchema = new Schema({
    accountId: String,
    accountCosts: {
        type: Schema.Types.Decimal128,
        default: 0,
        get: getCosts
    },
    id: false
}, {toJSON: {getters: true}});
现在你再也看不到了

最后一点提示(不,我还没有完成): 如果模式中有这样一个对象数组,会发生什么

var AccountingCostsSchema = new Schema({
    accountId: String,
    usersAndCosts: [{
        username: String,
        accountCosts: {
            type: Schema.Types.Decimal128,
            default: 0,
            get: getCosts
        }
    ],
    id: false
}, {toJSON: {getters: true}});
现在坏消息是:您不能继续使用此模式。现在有个好消息:你可以很容易地修复它。您需要为
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}});
结果将是相同的,您的
accountCosts
将显示为数字,没有双ID。
请记住,这当然是为
toJSON
启用getter,但您也可能需要为
toObject
启用getter,因为您可能需要对setter执行相同的操作。但是我们在这里讨论了JSON的getter。

toString()
不起作用。要解决这个问题,请看-@TheJoker,您是否能够像许多答案一样,在不将其转换为浮点数或字符串的情况下修复它?我希望它保持一个小数128。