Пока я создавал свое серверное приложение NestJs, я хотел хранить некоторые финансовые данные. Первый вопрос, с которым я столкнулся, заключался в том, какой тип схемы должен быть для хранения таких данных, где я хочу поддерживать точность данных.
Decimal128
оказался назначенным официальным кандидатом для хранения финансовых данных.
Вот моя первоначальная реализация схемы:
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import mongoose, { Decimal128, HydratedDocument, Types } from 'mongoose'; export type UserDocument = HydratedDocument<User>; @Schema({ toJSON: { getters: true, }, }) export class User { @Prop() firstName: string; @Prop() lastName: string; @Prop({ default: new Types.Decimal128('0'), type: Types.Decimal128, }) total_invested: Decimal128; @Prop({ default: new Types.Decimal128('0'), type: Types.Decimal128, }) target_returns: Decimal128; @Prop({ default: new Types.Decimal128('0'), type: Types.Decimal128, }) target_profit_percent: Decimal128; @Prop({ default: new Types.Decimal128('0'), type: Types.Decimal128, }) actual_returns: Decimal128; @Prop({ default: new Types.Decimal128('0'), type: Types.Decimal128, }) actual_profit_percent: Decimal128; } export const UserSchema = SchemaFactory.createForClass(User);
Была одна небольшая проблема, с которой я вскоре столкнулся. База данных вернет данные столбца Decimal128 в следующем формате:
{ "_id": "64d50a0bf9e3e104920dec6a", "firstName": "shiva", "lastName": "chaturvedi", "total_invested": { "$numberDecimal": "0" }, "target_returns": { "$numberDecimal": "0" }, "target_profit_percent": { "$numberDecimal": "0" }, "actual_returns": { "$numberDecimal": "0" }, "actual_profit_percent": { "$numberDecimal": "0" }, "__v": 0, "id": "64d50a0bf9e3e104920dec6a" }
… тогда как я хотел, чтобы база данных возвращала преобразованные результаты или, проще говоря, данные в старом добром формате пары ключ-значение.
Решение: используйте геттеры
Реализовать getters
в свойствах вашей схемы очень просто.
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import mongoose, { Decimal128, HydratedDocument, Types } from 'mongoose'; export type UserDocument = HydratedDocument<User>; @Schema() export class User { @Prop() firstName: string; @Prop() lastName: string; @Prop({ default: new Types.Decimal128('0'), type: Types.Decimal128, get: (v: Types.Decimal128) => v.toString(), }) total_invested: Decimal128; @Prop({ default: new Types.Decimal128('0'), type: Types.Decimal128, get: (v: Types.Decimal128) => v.toString(), }) target_returns: Decimal128; @Prop({ default: new Types.Decimal128('0'), type: Types.Decimal128, get: (v: Types.Decimal128) => v.toString(), }) target_profit_percent: Decimal128; @Prop({ default: new Types.Decimal128('0'), type: Types.Decimal128, get: (v: Types.Decimal128) => v.toString(), }) actual_returns: Decimal128; @Prop({ default: new Types.Decimal128('0'), type: Types.Decimal128, get: (v: Types.Decimal128) => v.toString(), }) actual_profit_percent: Decimal128; } export const UserSchema = SchemaFactory.createForClass(User);
Теперь давайте снова протестируем API.
«Что я упускаю?» — подумал я.
После небольшой прогулки по Интернету добрый самаритянин указал, что нам также нужно установить флаг getters
как true
в декораторе @Schema
, как показано ниже:
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import mongoose, { Decimal128, HydratedDocument, Types } from 'mongoose'; export type UserDocument = HydratedDocument<User>; @Schema({ toJSON: { getters: true, }, })
Это в основном позволяет свойствам выполнять/использовать свои собственные функции получения.
Тестируем снова!
Аллилуйя 🎉 🎉
Хотите узнать больше о типе Decimal128? Прочтите эту прекрасную статью, написанную Ken W. Alger на официальном сайте MongoDB.
Благодарственное письмо ❤️
Спасибо, что заглянули. Надеюсь, вы найдете этот блог полезным. Если да, то, пожалуйста, подпишитесь на меня и помогите мне набрать 1 000 подписчиков 🙏🏻. Это действительно побудит меня выпускать больше контента.
P.S.: Если вы чувствуете, что что-то можно улучшить или вам не хватает надлежащего объяснения, напишите мне в поле для комментариев или напишите мне на [email protected]. В конце концов, ты тоже можешь научить меня кое-чему.
Спасибо, что дочитали до конца. Пожалуйста, следите за автором и этой публикацией. Посетите Stackademic, чтобы узнать больше о том, как мы демократизируем бесплатное обучение программированию по всему миру.