MongoDB Java Driver: Convert BsonDocument to Document and back
Asked Answered
I

3

10

I am using the MongoDB Java Driver for my project to access my database from Java.

I usually use Document as it's quite easy to use and all methods in MongoDBCollection, such as find() work with it and return Document instances.

However, in some cases I want to use the equivalent BsonDocument which is more verbose but offers type-safety by implementing Map<String,BsonValue>, which Document does not have because it implements Map<String,Object>.

I am able to convert a Document into a BsonDocument with this:

BsonDocument bsonDoc = document.toBsonDocument(BsonDocument.class, MongoClient.getDefaultCodecRegistry());

The problem here is, that all methods in MongoDBCollection, like insertOne() only take Document instances, so I can not use these.


For me, it looks like there are 2 ways to solve this problem:

If the BsonDocument created by toBsonDocument() is in some way backed by the orginal Document, I could use the original Document instance even when I made modifications to the BsonDocument, because the original Document would reflect these changes, right? Does it work this way or is the BsonDocument just a copy?

The second way would be to convert from BsonDocument back to Document. Is this in some way possible?


Thanks in advance!

Insane answered 13/3, 2018 at 18:1 Comment(4)
are you using any ORM? If not please check Morphia:mongodb.github.io/morphia, no need to change to and fro from BsonDocumentRabinowitz
have you tried passing BsonDocument to the insertOne() ? It should work.Infringe
@Rabinowitz thanks! I will look into that! Maybe that will make the whole thing easier.Insane
@Veeram With your comment I was able to find out that there is another getCollection I can use to get other types of documents in the collection instance. I will look into this and see if I can get it to work!Insane
A
8

Assuming you have an instance of CodecRegistry, you can convert BsonDocument to Document and vice-versa using this adapter:

public class DocumentAdapter {
    private final CodecRegistry registry;
    private final Codec<Document> codec;

    public DocumentAdapter(CodecRegistry registry) {
        this.registry = registry;
        this.codec = registry.get(Document.class);
    }

    public Document fromBson(BsonDocument bson) {
        return codec.decode(bson.asBsonReader(), DecoderContext.builder().build());
    }

    public BsonDocument toBson(Document document) {
        return document.toBsonDocument(BsonDocument.class, registry);
    }
}
Ammo answered 30/7, 2019 at 8:46 Comment(2)
This is great. I took a peak at DocumentCodec and it looks like decode() is also threadsafe!Anaxagoras
You can get a codec registry via mongodb.github.io/mongo-java-driver/3.12/javadoc/com/mongodb/…Architecture
C
4
public static Document bsonToDocument(BsonDocument bsonDocument) {
    DocumentCodec codec = new DocumentCodec();
    DecoderContext decoderContext = DecoderContext.builder().build();
    return codec.decode(new BsonDocumentReader(bsonDocument), decoderContext);
}
Cameroun answered 6/8, 2020 at 5:57 Comment(0)
V
-1

I use this "workaround" of converting the BsonDocument to string and then the string to Document.
Might be useful depending the scenario.

final BsonDocument json = BsonDocument.parse("{}");
final Document parsedJson = Document.parse(json.toJson());

or simply

final Document json = Document.parse(BsonDocument.parse("{}").toJson());
Vocabulary answered 6/10, 2020 at 14:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.