4

While debugging a mongoose callback I found out that either underscore.js or the JavaScript language itself seems to have a problem with big numbers.

In the example below, I store a small number, and a String that contains an ObjectId from mongoose (24 digit number), in order to show the problem as clearly as possible.

var users = ["32", "300000000000000000000002"];
alert(_.contains(users, "32")); // true
alert(_.contains(users, (32).toString())); // true
alert(_.contains(users, "300000000000000000000002")); // true
alert(_.contains(users, (300000000000000000000002).toString())); // false - wait wat ?

My question is, of course, how to make the last call return true ?

I would prefer not to convert the array users to an array of numbers, because (1) the array might be huge in a production context, and (2) I may need to do other operations on the array.

blagae
  • 2,342
  • 1
  • 27
  • 48
  • 4
    `(300000000000000000000002).toString() === "3e+23"` – Bergi Nov 27 '15 at 12:33
  • 2
    24 digits is just to much for js http://stackoverflow.com/questions/307179/what-is-javascripts-highest-integer-value-that-a-number-can-go-to-without-losin – Pevara Nov 27 '15 at 12:34
  • While your diagnostic input is appreciated and has helped me, I'm still looking for a solution – blagae Nov 27 '15 at 12:46
  • ObjectId's are 24-byte _strings_, not 24-digit _numbers_. Why not limit the search input to just strings? – robertklep Nov 27 '15 at 13:49

2 Answers2

3

The last returns "3e+23" which is not equals to "300000000000000000000002"

styvane
  • 59,869
  • 19
  • 150
  • 156
1

The problem was always that I get an input String which is automatically converted to a number (by a library). So I only had to make the 'foreign key' a smaller number. I eventually created a custom number autogenerate function to circumvent this problem:

var autoIncrement = require('mongoose-auto-increment');
var address = require('./Address');
var connection = mongoose.createConnection(address.mongo());
autoIncrement.initialize(connection);

var UserSchema = new mongoose.Schema({ /* property definitions */});
mongoose.model('User', UserSchema);

UserSchema.plugin(autoIncrement.plugin, {
    model: 'User',
    startAt: 10000001
});

As a result, I had to change the referencing mechanism:

var GroupSchema = new mongoose.Schema({
    users: [{type: Number, ref: 'User'}],
    /* other property definitions */
});
blagae
  • 2,342
  • 1
  • 27
  • 48