Javascript mongoose在数据库中插入十进制128数据,保存为所需嵌套文档的字符串
对于此示例:Javascript mongoose在数据库中插入十进制128数据,保存为所需嵌套文档的字符串,javascript,node.js,mongodb,mongoose,decimal,Javascript,Node.js,Mongodb,Mongoose,Decimal,对于此示例: 数据集books.json文件: [ { "addr": "address1", "book": "book1", "rawPrice": "9.135027", "prices": [ {"net": "9.13502
数据集
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"
}
}
]
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();
});
});
插入代码app.ts
文件:
[
{
"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"
}
}
]
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")
}
]
price: {
net: decimalOptionalField,
gross: decimalOptionalField,
},
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,
}
);
如结果所示,rawPrice
和prices
字段具有类型为Decimal128
的正确值,但对于嵌套文档price
的类型不正确,值保存为字符串。
但是,如果在模式中定义了价格,而没有如下详细对象:
[
{
"_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")
}
]
price: {
net: decimalOptionalField,
gross: decimalOptionalField,
},
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,
}
);
我得到了正确的结果:
[
{
"_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")
}
]
但我需要该字段为必填项。因此,我如何确保将值保存为小数128,同时也将其设置为必需值?您的模式与数据集之间存在问题,并且您在Mongoose 5+中遇到异常,
price
变为混合路径
首先,检查您是否需要。这两样你都试过了。如果我们假设您希望得到与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',
}
);
或者您可以使用选项typepojotomix:false
如下:
[
{
"_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")
}
]
price: {
net: decimalOptionalField,
gross: decimalOptionalField,
},
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,
}
);
感谢您的链接,我最终使用了typepojotomix:false
选项,它看起来比为每个嵌套字段创建新模式更简单。