![](/img/trans.png)
[英]Extract Decimal from Decimal128 with Mongoose - MongoDB
[英]mongoose insert decimal128 data in db saved as string for required nested documents
對於這個例子:
數據集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")
}
]
如結果所示,字段rawPrice
和prices
具有類型為Decimal128
的正確值,但對於嵌套文檔price
,其類型不正確,該值被保存為字符串。 但是當價格在沒有詳細 object 的架構中定義時,如下所示:
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,
}
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.