How to modify a BSON document

1,258 views
Skip to first unread message

Vin

unread,
May 11, 2017, 5:28:42 AM5/11/17
to mongodb-user
Hi,
I'm using bsoncxx and I'm having a hard time to understand how to modify a BSON document.

let's say I have this input :
 1) a JSON document  like :
{
 "name" : "john",
 "address" : 
  {
    "number" : "235",
    "Town" : " New York city"
  }
}

2) a rule set of modification directives to the BSON document :
a) convert value of address.number from string to int32
b) add the field address.Country with value "USA" to the document.
c) remove the field address.Town from the document.

from https://mongodb.github.io/mongo-cxx-driver/api/current/namespacebsoncxx.html I understand I can convert my JSON std::string to a BSON using
the instruction 
  document::value myBsonDoc = bsoncxx::from_json(myJsonString);
but then, what to do next with myBsonDoc for each of the actions needed in a) b) and c) ?

Thank you.

Vin

unread,
May 12, 2017, 2:03:33 AM5/12/17
to mongodb-user
What's the solution the Mongo team would choose for this ?

Should I parse my json string with a third party JSON library (like Poco::Json), do the modification job pointed in 2a), 2b), 2c) then convert back my Json object to string then use 
document::value myBsonDoc = bsoncxx::from_json(myModifiedJsonString);

?

Thank you for your help.

Sam Rossi

unread,
May 16, 2017, 12:31:22 PM5/16/17
to mongodb-user
Hi Vin! There currently isn't any way to modify BSON documents in bsoncxx; internally, the documents are only represented as an array of bytes, and we use libbson to read from it. Without using any third party libraries, the most idiomatic way to do what you want would be to parse the string with bsoncxx::from_json and then to recurse over it and build up a new document, making changes wherever necessary.

Let me know if you have any other questions or I didn't explain this clearly, and thanks for using the C++ driver!

Vincent Dautremont

unread,
May 17, 2017, 3:18:09 AM5/17/17
to mongod...@googlegroups.com
Thank you Sam,
That's what I thought, and I've used bsoncxx::builder::stream::document to build a new document.

But I must say it's a bit sad to miss such a feature where you would just express the diff/changes you want from a base bsoncxx::document::value, and later ask the driver to generate a new document with these changes included.

I hope future updates of the driver will go in this direction.

--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: https://docs.mongodb.com/manual/support/
---
You received this message because you are subscribed to a topic in the Google Groups "mongodb-user" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mongodb-user/mXUP7iEFxXo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mongodb-user+unsubscribe@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at https://groups.google.com/group/mongodb-user.
To view this discussion on the web visit https://groups.google.com/d/msgid/mongodb-user/b9d876ff-df69-44f6-a53a-0c0b35e304d0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

Andrew Morrow

unread,
May 17, 2017, 11:20:31 AM5/17/17
to mongod...@googlegroups.com

Adding support for mutation to/above a BSON library is tricky to get right.

If you are interested in efficiency, then you most likely don't want to first de-serialize the whole document into a complete tree of objects scattered all over the heap, then apply mutations, and then re-serialize. Instead, you want something more like copy-on-write, where the underlying BSON buffer remains contiguous, and mutations are stored on the side. The server codebase does have such a facility (in particular, see document.cpp in that directory), built above its internal BSON library, but I'm not aware of any drivers that currently offer similar functionality.

It may be the case that you could build an analogous abstraction above the bsoncxx library, though I haven't thought too hard about how to do it or whether it is in fact possible given the current API to bsoncxx.

Thanks,
Andrew



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+unsubscribe@googlegroups.com.

To post to this group, send email to mongod...@googlegroups.com.
Visit this group at https://groups.google.com/group/mongodb-user.

Sam Rossi

unread,
May 17, 2017, 1:21:06 PM5/17/17
to mongodb-user
Interestingly, the functionality you describe (expressing a diff and generating a new document) is something we recently found necessary to implement in our testing code, although it's currently only on master (i.e. not released) and isn't part of the public API. If you're interested in seeing how we solved the problem, you can see it here (and in the corresponding .cpp file). We're not sure yet if there are use cases that it isn't flexible enough to handle (hence not releasing it as part of the API), but feel free to draw inspiration from it if you'd like to implement something like that for your own use.

Vincent Dautremont

unread,
May 18, 2017, 4:12:47 AM5/18/17
to mongod...@googlegroups.com
Thank you, that's really interesting,
I'll reuse this code for sure if I have new transformation needs.

From what I've read, I'll just need to add code to handle transformation that adds K+V to a Document (and V to an Array).


--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: https://docs.mongodb.com/manual/support/
---
You received this message because you are subscribed to a topic in the Google Groups "mongodb-user" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mongodb-user/mXUP7iEFxXo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mongodb-user+unsubscribe@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at https://groups.google.com/group/mongodb-user.

For more options, visit https://groups.google.com/d/optout.
Message has been deleted
Message has been deleted

Sam Rossi

unread,
May 18, 2017, 2:07:18 PM5/18/17
to mongodb-user
Yep! Each key/value pair will be passed into the function you provide, and whatever you return will be appended in its place (so you just return what was passed in if you don't want to change it). stdx::optional::nullopt will be passed in as the key for array values, and if the value you're returning is non-owning, append it to the array pointer passed in so it lives long enough.

You can see some examples of how we use it here, although they're somewhat complex, so it might not be super clear what the transformations are intended to do.
Reply all
Reply to author
Forward
0 new messages