Decimal / Float in mongoose for node.js

Mongodbnode.jsMongoose

Mongodb Problem Overview


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 ?

Mongodb Solutions


Solution 1 - Mongodb

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.

Solution 2 - Mongodb

Solution 3 - Mongodb

You can use the Decimal128 in Mongoose Schema as

speed:{
type:mongoose.Types.Decimal128
}

Solution 4 - Mongodb

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

Solution 5 - Mongodb

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLucView Question on Stackoverflow
Solution 1 - MongodbAndrew OrsichView Answer on Stackoverflow
Solution 2 - MongodbMuzaffar MahmoodView Answer on Stackoverflow
Solution 3 - MongodbPranab DasView Answer on Stackoverflow
Solution 4 - MongodbTheEhsanSarsharView Answer on Stackoverflow
Solution 5 - Mongodb99problemsView Answer on Stackoverflow