【问题标题】:mongoDB returning with $numberDecimal in the response of a querymongoDB 在查询响应中返回 $numberDecimal
【发布时间】:2020-08-06 09:04:27
【问题描述】:

下面是我的猫鼬模式

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

accountingCosts 收集

文本模式视图中的数据

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

文本模式视图中的数据

我的查询

db.getCollection('accountingCosts').find({'accountId': '4e8c1180d85de1704ce12110'})

查询结果

"accountCosts": {
      "$numberDecimal": "123.00"
}

我尝试在架构上编写一个 getter 函数,就像我有一个 setter 函数一样。但它不起作用

get: function(value) {
      return value.toString();
}

我的预期输出只是一个普通属性,其名称和值如下所示

"accountCosts": "123.00"

【问题讨论】:

  • toString() 不起作用。有关解决方案,请参阅 - stackoverflow.com/a/66320724/984471
  • @TheJoker,您是否能够修复它而不像许多答案那样将其转换为浮点数或字符串?我希望它保持为 Decimal128 数字。

标签: node.js mongodb mongoose mongoose-schema


【解决方案1】:

我相信你找到了解决方案,但我也会在这里写下来,这样谁会在这里找到解决方案。 您使用 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 documents

默认情况下,Mongoose 会为您的每个模式分配一个 id 虚拟 getter,它将文档的 _id 字段转换为字符串,或者在 ObjectIds 的情况下,返回其 hexString。如果您不希望将 id getter 添加到您的架构中,您可以通过在架构构建时传递此选项来禁用它。

我们如何避免它?我们可以在我们的架构中添加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 启用它们,因为您可能需要对setter 执行相同的操作。但是我们在这里讨论了 JSON 的 getter。

【讨论】:

    猜你喜欢
    • 2015-01-02
    • 1970-01-01
    • 2020-01-22
    • 2020-02-06
    • 2014-02-06
    • 2022-01-03
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多