71

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 ?

1
  • 1
    var car = new Car({brand: "", speed: 0.5}); Commented Dec 4, 2013 at 21:08

5 Answers 5

99

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.

Sign up to request clarification or add additional context in comments.

6 Comments

thanks a lot . But, in this article, it seems it's more the other way round, ie to force a float into an integer, right ? Sorry, I maybe misanderstood the thing.
@Luc: Exactly, in article about forcing float into an integer. But it's mean that you can store float value in field with type Number. So Number type should be used for both types: integer and float.
@Bugain13, thanks a lot, you'r right. There is something strange I should have done because it was not working at first place. Thanks a lot for your help !!!!
You should be warned: When using number and aggregations like summations with Mongoose you will get Ulps problems. (insertion of a 1 after dozens of Zeros behind the point)
it just convert float to int. and nothing else
|
11

You can use the Decimal128 in Mongoose Schema as

speed:{
type:mongoose.Types.Decimal128
}

Comments

10

Yes you can use the Decimal128 type.

https://mongoosejs.com/docs/api.html#mongoose_Mongoose-Decimal128

Comments

2

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

2 Comments

Como faria o uso?
@EzequielTavares waa
-4

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.

Edit: I have just found that in 2018, the mongoose added support for Decimal128 so you can simply just use mongoose.Types.Decimal128 for your schema

1 Comment

No it won't. You can store numbers like 25.50 as a number and it won't be stored as a string

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.