Zeiko
Zeiko

Reputation: 41

Converting a BSON document containing an array to JSON, removes the array from the converted JSON (C++)

I have a document that looks like this:

{
    "_id" : ObjectId("5bd37e0128f41363c0006ac2"),
    "source" : "Forge",
    "data" : [ 
        {
            "symbol" : "EURUSD",
            "bid" : 1.14021,
            "ask" : 1.14024,
            "price" : 1.14023,
            "timestamp" : 1540587008
        }
    ]
}

I want to get the data part out of the bson document, which I'm doing by this code:

auto dataDocument = view["data"].get_value().get_document();
auto textMessage = bsoncxx::to_json(dataDocument);

However the output when field data is an array as in the example is this:

{
    "0": {
        "symbol": "EURUSD",
        "bid": 1.1405199999999999783,
        "ask": 1.1405300000000000438,
        "price": 1.1405300000000000438,
        "timestamp": 1540580136
    }
}

Instead of this (correct):

[{
        "symbol": "EURUSD",
        "bid": 1.14056,
        "ask": 1.14057,
        "price": 1.14057,
        "timestamp": 1540580927
    }
]

How come the brackets are removed and instead a "0" field is put there instead?

If I do a to_json on the whole document the array is kept, its only when I do to_json on the field data which is an array the error happens.

Any ideas?

Update, here's a working example which reproduce my issue:

#include <mongocxx/instance.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>

int main()
{
    mongocxx::instance inst{};
    auto conn = mongocxx::client{ mongocxx::uri{} };
    auto collection = conn["QuantBot"]["test"];

    auto jsonDoc = R"(    
    {
        "source" : "Forge",
        "data" : [ 
            {
                "symbol" : "EURUSD",
                "bid" : 1.13875,
                "ask" : 1.13925,
                "price" : 1.139,
                "timestamp" : 1540758149
            }
        ]
    }
    )";

    auto bsonDocument = bsoncxx::from_json(jsonDoc);
    collection.insert_one(bsonDocument.view());

    auto cursor = std::make_unique<mongocxx::cursor>(collection.find({}));
    auto cursorIt = std::make_unique<mongocxx::cursor::iterator>(cursor->begin());
    auto view = bsoncxx::document::view(**cursorIt);
    auto dataDocument = view["data"].get_value().get_document();
    auto textMessage = bsoncxx::to_json(dataDocument);
}

Upvotes: 4

Views: 1766

Answers (1)

acm
acm

Reputation: 12727

I believe the problem is here: get_value().get_document(). Try making that say get_value().get_array() instead. Also note that you should be checking the type of the value returned by get_value before calling any methods on it. This is working more by good luck than by good design. The reason that you are seeing a literal zero there is because BSON arrays are represented as documents with integral keys. You have, effectively, cast an array to a document, so it is printing as a document with numeric keys, instead of an array as intended.

Upvotes: 2

Related Questions