Preserving types in BSON -> JSON -> BSON round trip (C++)

174 views
Skip to first unread message

Da Joghurt

unread,
Jun 24, 2014, 1:16:42 PM6/24/14
to mongod...@googlegroups.com

Hi all,

when I convert a BSON object to a JSON string using the 

BSONObj::jsonString(mongo::strict)
method of the C++ BSONObj implementation, field values of type double which are equal to an integer number are printed without decimal point (e.g. 2.0 gets 2).

When I then convert the JSON string back to a BSON object via

mongo::fromjSON
the parser creates an element of type int for this value, i.e. the type of the field has changed after the round trip. Applications which expect a certain field type hence fail.

I am wondering whether there is any way to avoid this behaviour and correctly preserve the types.

I understand that pure JSON does not support this type distinction, but since MongoDB claims to have an extended JSON parser that recognizes type information, I would expect that such undesired type conversions can be avoided.

Any help is greatly appreciated - this is currently a show stopper for me ...


Tyler Brock

unread,
Jun 24, 2014, 3:02:09 PM6/24/14
to mongod...@googlegroups.com
Hey Da,

Sorry you are having trouble.

Try using mongo::TenGen as the format specifier instead.

-Tyler


--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: http://www.mongodb.org/about/support/.
---
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user...@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at http://groups.google.com/group/mongodb-user.
To view this discussion on the web visit https://groups.google.com/d/msgid/mongodb-user/9df76f5e-43c8-45e3-86d7-73c7be41b939%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Da Joghurt

unread,
Jun 25, 2014, 12:08:03 PM6/25/14
to mongod...@googlegroups.com
Hey Tylor,

thank you very much for your suggestion. Unfortunately, mongo::TenGen is no different in this respect than mongo::Strict.

The only format that seems to make a difference at all is mongo::JS: it writes "NumberInt(3)" when it really means the integer, otherwise only "3". However, this still means that "3" will be parsed into an int when reading back the JSON string, so no solution.

In my opinion, the BSONObj::jsonString method should simply append a dot to a number when it is a float, regardless of whether the float is equal to an int. In this case, the JSON string could be converted back correctly.

Is there a reason why this does not happen?


Tyler Brock

unread,
Jun 26, 2014, 11:35:09 AM6/26/14
to mongod...@googlegroups.com
Yes, the reason is that there is no standard for it. JSON only supports a single numeric type so converting to JSON is inherently lossy.

This seems to work for me:

        BSONObjBuilder bob;
        bob.append("int", 123);
        bob.append("double", 123.123);
        BSONObj obj = bob.obj();

        std::cout << "int: " << std::hex << int(
            fromjson(tojson(obj, TenGen)).getField("int").type()
        ) << std::endl;

        std::cout << "double: " << std::hex << int(
            fromjson(tojson(obj, TenGen)).getField("double").type()
        ) << std::endl;

Prints the following correct bson types:

    int: 10
    double: 1





--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: http://www.mongodb.org/about/support/.
---
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user...@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at http://groups.google.com/group/mongodb-user.

Da Joghurt

unread,
Jun 26, 2014, 12:20:02 PM6/26/14
to mongod...@googlegroups.com
Hi Tyler,

thanks for answering. Your code works for me as well. However, my case is slightly different: If you make the double equal to an integer value, it will fail:

bob.append("double", 123.0);

I completely understand that pure JSON does not make a difference between int and float. But since mongodb claims to have an extended JSON understanding that preserves types, I believe it would be a good option to have jsonString() append a dot to a number, when the field type is double. This would allow to read back correct types for parsers that care, and would still be parseable for everybody else without breaking anything.

Tyler Brock

unread,
Aug 29, 2014, 2:19:51 PM8/29/14
to mongod...@googlegroups.com
Yeah, i see. That is interesting. In that case the round trip will not work.


--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: http://www.mongodb.org/about/support/.
---
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user...@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at http://groups.google.com/group/mongodb-user.
Reply all
Reply to author
Forward
0 new messages