mongoose在数据库中插入decimal128数据,该数据保存为所需嵌套文档的字符串



例如:
数据集books.json文件:

[
{
"addr": "address1",
"book": "book1",
"rawPrice": "9.135027",
"prices": [
{"net": "9.135027"},
{"gross": "10.15003"}
],
"price": {
"net": "9.135027",
"gross": "10.15003"
}
},
{
"addr": "address2",
"book": "book1",
"rawPrice": "19.351017",
"prices": [
{"net": "19.351017"},
{"gross": "21.50113"}
],
"price": {
"net": "19.351017",
"gross": "21.50113"
}
}
]

插入代码app.ts文件:

import { readFileSync } from 'fs';
import { model, connect, Schema } from 'mongoose';
const uri = 'mongodb://localhost:27017/db-tests';
const log = (data: any) => console.log(JSON.stringify(data, null, 2));
const data = readFileSync('./books.json', { encoding:'utf8', flag:'r' });
const decimalField = {
default: 0,
required: true,
type: Schema.Types.Decimal128,
get: (v: Schema.Types.Decimal128) => v.toString(),
};
const decimalOptionalField = {
default: 0,
type: Schema.Types.Decimal128,
get: (v: Schema.Types.Decimal128) => v.toString(),
};
const booksScema = new Schema(
{
addr: { $type: String },
book: { $type: String },
rawPrice: decimalField,
price: {
required: true,
type: {
net: decimalField,
gross: decimalField,
},
},
prices: {
required: true,
type: [
{
net: decimalOptionalField,
gross: decimalOptionalField,
}
],
},
},
{ timestamps: true, versionKey: false }
);
connect(uri, { useNewUrlParser: true, useUnifiedTopology: true }).then((mongoose) => {
const booksModel = model('books', booksScema);
booksModel.insertMany(JSON.parse(data)).then((insertedData) => {
log(insertedData);
mongoose.connection.close();
});
});

结果在数据库中插入的数据如下:

[
{
"_id" : ObjectId("60006333e861c6c0b10778be"),
"rawPrice" : NumberDecimal("9.135027"),
"prices" : [ 
{
"net" : NumberDecimal("9.135027"),
"_id" : ObjectId("60006333e861c6c0b10778bf")
}, 
{
"gross" : NumberDecimal("10.15003"),
"_id" : ObjectId("60006333e861c6c0b10778c0")
}
],
"price" : {
"net" : "9.135027",
"gross" : "10.15003"
},
"createdAt" : ISODate("2021-01-14T15:28:51.810Z"),
"updatedAt" : ISODate("2021-01-14T15:28:51.810Z")
}
{
"_id" : ObjectId("60006333e861c6c0b10778c1"),
"rawPrice" : NumberDecimal("19.351017"),
"prices" : [ 
{
"net" : NumberDecimal("19.351017"),
"_id" : ObjectId("60006333e861c6c0b10778c2")
}, 
{
"gross" : NumberDecimal("21.50113"),
"_id" : ObjectId("60006333e861c6c0b10778c3")
}
],
"price" : {
"net" : "19.351017",
"gross" : "21.50113"
},
"createdAt" : ISODate("2021-01-14T15:28:51.812Z"),
"updatedAt" : ISODate("2021-01-14T15:28:51.812Z")
}
]

如结果所示,字段rawPriceprices具有类型为Decimal128的正确值,但对于嵌套文档price,其类型不正确,该值将保存为字符串。但是当价格在模式中定义时,没有像这样的详细对象:

price: {
net: decimalOptionalField,
gross: decimalOptionalField,
},

我得到了正确的结果:

[
{
"_id" : ObjectId("600064b60d223c13635a22dd"),
"price" : {
"net" : NumberDecimal("9.135027"),
"gross" : NumberDecimal("10.15003")
},
"rawPrice" : NumberDecimal("9.135027"),
"prices" : [ 
{
"net" : NumberDecimal("9.135027"),
"gross" : NumberDecimal("0"),
"_id" : ObjectId("600064b60d223c13635a22de")
}, 
{
"net" : NumberDecimal("0"),
"gross" : NumberDecimal("10.15003"),
"_id" : ObjectId("600064b60d223c13635a22df")
}
],
"createdAt" : ISODate("2021-01-14T15:35:18.452Z"),
"updatedAt" : ISODate("2021-01-14T15:35:18.452Z")
},
{
"_id" : ObjectId("600064b60d223c13635a22e0"),
"price" : {
"net" : NumberDecimal("19.351017"),
"gross" : NumberDecimal("21.50113")
},
"rawPrice" : NumberDecimal("19.351017"),
"prices" : [ 
{
"net" : NumberDecimal("19.351017"),
"gross" : NumberDecimal("0"),
"_id" : ObjectId("600064b60d223c13635a22e1")
}, 
{
"net" : NumberDecimal("0"),
"gross" : NumberDecimal("21.50113"),
"_id" : ObjectId("600064b60d223c13635a22e2")
}
],
"createdAt" : ISODate("2021-01-14T15:35:18.454Z"),
"updatedAt" : ISODate("2021-01-14T15:35:18.454Z")
}
]

但我需要这个领域
那么,我如何确保将该值保存为Decimal128,同时也使其成为必需值呢?

您的模式与数据集中存在问题,并且您在Mongoose 5+中遇到异常,其中price变为Mixed路径。

首先,检查是否要嵌套路径或子文档。在这里,你试着两者兼得。如果我们假设您想要与prices(嵌套文档(中相同的结果,那么您的模式将是这样的。

const decimalField = {
default: 0,
required: true,
type: Schema.Types.Decimal128,
get: (v: Schema.Types.Decimal128) => v.toString(),
};
const priceSchema = new Schema({
net: decimalField,
gross: decimalField,
});
const booksScema = new Schema(
{
addr: String,
book: String ,
rawPrice: decimalField,
price: priceSchema,
prices: {
type: priceSchema,
validate: (v: any) => Array.isArray(v) && v.length > 0,
},
},
{
timestamps: true,
versionKey: false,
// useNestedStrict: true, https://mongoosejs.com/docs/guide.html#useNestedStrict
// strict: 'throw',
}
);

或者你可以使用选项typePojoToMixed: false,如下所示:

const decimalField = {
default: 0,
required: true,
type: Schema.Types.Decimal128,
get: (v: Schema.Types.Decimal128) => v.toString(),
};
const decimalOptionalField = {
default: 0,
type: Schema.Types.Decimal128,
get: (v: Schema.Types.Decimal128) => v.toString()
};
const booksScema = new Schema(
{
addr: String,
book: String ,
rawPrice: decimalField,
price: {
required: true,
type: {
net: decimalField,
gross: decimalField,
},
},
prices: {
required: true,
type: [
{
net: decimalOptionalField,
gross: decimalOptionalField,
}
],
},
},
{
timestamps: true,
versionKey: false,
typePojoToMixed: false,
}
);

最新更新