Question

I have quite complicated data structure in MongoDB. My custom arrays are represented by items + Length field (it's an another story why JSON arrays doesn't work in my particular case). The code that saves and updates Length fields is generic and always provide ints, not floats or doubles. Values of Length fields have been always 32-bit ints until yesterday when I failed to convert one of them to int32 because it's actually double.

So I have one problematic document (all the same hierarchical structure) among thousand others. First of all I exported it to JSON. The value of problematic field is 56 and in JSON it looks like:

    ...
        "55": {
        ...
        },
        "Length": 56
    },
    ...

Then I imported that JSON to local MongoDB server for investigation and again when I get that Length field in C# driver its type is double. Other Length fields in the same document are ints. This makes me suspect C# driver for this nasty behaviour. To separate MongoDB server and C# driver I need to check this value type in MongoDB server but I don't know how. Trying

typeof db.collection.findOne({...}, {"path.to.value": 1}).path.to.value

prints number for all my Length values. But I don't believe MongoDB here because simple test:

db.test.save({fint: NumberInt(0)})
typeof db.test.findOne().fint

prints number too.

According to MongoDB BSON Types internal types are doubles and ints, it's only in MongoDB Shell they look like numbers.

Now, the main question is have you ever seen something similar or have any idea what is wrong?

And more specific question: how to check exact internal data type of value?

MongoDB 2.4.6, C# driver 1.8.1, seen on Windows and Linux

UPDATE

The problem was in completely different place. I was confused by the fact that importing document from JSON (by JavaScript) makes all numbers to be double MongoDB internal type. Accepted answer helped me to find this out.

Was it helpful?

Solution 2

I haven't encountered anything similar.

Regarding your second question, I use MongoVUE and it has a Type column:

enter image description here

OTHER TIPS

First of all - JavaScript (MongoDB shell) doesn't distinguish double and int numeric types so you can't check that using MongoDB shell:

typeof 1 === typeof 1.1 // true

You can do a query that uses $type operator to query the fields by their type:

// 1 for double, 16 for int32, 18 for int64
db.myColl.find({ fint : { $type : 1 } }); 

It's probably easier to see the type of a field using a GUI client like robomongo or MongoVUE.

I know that you're using C# driver, but this can maybe give you an idea what's happening; perl driver documentation describes difference with numbers when using 32/64 bit integers:

  • Programmer 1 saves an int on a 32-bit platform.
  • Programmer 2 retrieves the document on a 64-bit platform and re-saves it, effectively converting it to a 64-bit int.
  • Programmer 1 retrieves the document on their 32-bit machine, which decodes the 64-bit int as a double.

Edit:

I just noticed your comment regarding importing data using the MongoDB shell. You can take a look at MongoDB documentation regarding MongoDB shell data types to see the default behaviour:

By default, the mongo shell treats all numbers as floating-point values. The mongo shell provides the NumberInt() constructor to explicitly specify 32-bit integers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top