Decimal / Float in mongoose for node.js
I start my first test app on node.js / mongoDB / mongoose, this is a very simple app that aims to crate record in DB and retrieve them.
I create a model like:
var Car = new Schema({
brand : String,
speed : Number,
date : { type: Date, default: Date.now }
});
This is working fine, except that I would like to be able to provide a float value for speed instead of the integer one. I gave a try to Decimal and Float but开发者_如何学运维 none of them are working. I did not find in the documentation either.
Any idea ?
I've searched a bit and found this article stating that for storing float values you must use Number
type. You can store any float value in speed
field.
Yes you can use the Decimal128
type.
https://mongoosejs.com/docs/api.html#mongoose_Mongoose-Decimal128
You can use the Decimal128 in Mongoose Schema as
speed:{
type:mongoose.Types.Decimal128
}
you can create your custom one. like so
'use strict';
const mongoose = require('mongoose');
class DoubleType extends Number {
constructor(v) {
super(v);
this.value = v;
this._bsontype = 'Double';
}
toBSON() {
return this;
}
}
class Double extends mongoose.SchemaType {
constructor(key, options) {
super(key, options, 'Double');
Object.assign(this.$conditionalHandlers, {
'$lt': val => this.castForQuery(val),
'$lte': val => this.castForQuery(val),
'$gt': val => this.castForQuery(val),
'$gte': val => this.castForQuery(val),
});
}
cast(val) {
if (val == null) {
return val;
}
if (val._bsontype === 'Double') {
return new DoubleType(val.value);
}
const _val = Number(val);
if (isNaN(_val)) {
throw new mongoose.SchemaType.CastError('Double',
val + ' is not a valid double');
}
return new DoubleType(_val);
}
}
mongoose.Schema.Types.Double = Double;
mongoose.Types.Double = DoubleType;
module.exports = Double;
source is copied from @mongoosejs/double
While the mongoDB fully supports float type, the mongoose supports only type of Number which is integer. If you try to save to mongoDB float number using mongooses type of Number it will be converted to string.
To sort this out, you will need to load some plugin for mongoose which will extend its value types. There are some plugins which work best with currencies or dates, but in your case I would use https://www.npmjs.com/package/mongoose-double.
Your model after changes would look something like this:
var mongoose = require('mongoose')
require('mongoose-double')(mongoose);
var SchemaTypes = mongoose.Schema.Types;
var Car = new Schema({
brand: {
type: String
},
speed: {
type: SchemaTypes.Double
},
date: {
type: Date,
default: Date.now
}
});
Hope it helps.
精彩评论