簡體   English   中英

mongoose 在數據庫中插入 decimal128 數據,保存為所需嵌套文檔的字符串

[英]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")
  }
]

如結果所示,字段rawPriceprices具有類型為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM