Documents

For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

Documents

Overview

In this guide, you can learn how to use documents in the MongoDB Java Driver.

A MongoDB document is a data structure that contains key/value fields in binary JSON (BSON) format. You can use documents and the data they contain in their fields to store data as well as issue commands or queries in MongoDB.

For more information about the terminology, structure, and limitations of documents, read our page on Documents in the MongoDB manual.

The MongoDB Java driver and BSON library include the following classes that help you access and manipulate the BSON data in documents:

Name Package Implements Map Recommended Usage
Document org.bson Yes, implements Map<String, Object> When you want a flexible and concise data representation.
BsonDocument org.bson Yes, implements Map<String, BsonValue> When you need a type-safe API.
JsonObject org.bson.json No When you only want to work with JSON strings.
BasicDBObject com.mongodb No When you are migrating your application from a legacy driver version.

While you can use any of these classes in your application, we recommend that you use the Document class since it can concisely represent dynamically structured documents of any complexity. It implements the Map<String, Object> interface which enables it to use loosely-typed values.

Document

The Document class offers a flexible representation of a BSON document. You can access and manipulate fields using Java types from the standard library with this class. See the following table for mappings between frequently-used BSON and Java types:

BSON type Java type
Array java.util.List
Binary org.bson.types.Binary
Boolean java.lang.Boolean
Date java.util.Date
Document org.bson.Document
Double java.lang.Double
Int32 java.lang.Integer
Int64 java.lang.Long
Null null
ObjectId org.bson.types.ObjectId
String java.lang.String

The preceding mapping table shows the default mapping when working with the Document class. You can customize the type mapping by specifying a custom codec. For more information about customizing mapped types, see our guide on using [Codecs.](https://www.mongodb.com/docs/drivers/java/sync/current/data-formats/codecs.md#std-label-fundamentals-codecs

In the following code snippet, we show how to instantiate and build a sample Document instance representing a document containing several different field types:

Document author = new Document("_id", new ObjectId())
    .append("name", "Gabriel García Márquez")
    .append("dateOfDeath",
            Date.from(LocalDate.of(2014, 4, 17).atStartOfDay(ZoneId.systemDefault()).toInstant()))
    .append("novels", Arrays.asList(
        new Document("title", "One Hundred Years of Solitude")
            .append("yearPublished", 1967),
        new Document("title", "Chronicle of a Death Foretold")
            .append("yearPublished", 1981),
        new Document("title", "Love in the Time of Cholera")
            .append("yearPublished", 1985)));

To insert this document into a collection, instantiate a collection using the getCollection() method and call the [insertOne](https://www.mongodb.com/docs/drivers/java/sync/current/crud/insert.md#std-label-java-insertone operation as follows:

// MongoClient mongoClient = <code to instantiate your client>;

MongoDatabase database = mongoClient.getDatabase("fundamentals_data");
MongoCollection<Document> collection = database.getCollection("authors");

InsertOneResult result = collection.insertOne(author);

Once you perform a successful insert, you can retrieve the sample document data from the collection using the following code:

import com.mongodb.client.model.Filters;
// <MongoCollection setup code here>

Document doc = collection.find(Filters.eq("name", "Gabriel García Márquez")).first();
if (doc != null) {
    System.out.println("_id: " + doc.getObjectId("_id")
        + ", name: " + doc.getString("name")
        + ", dateOfDeath: " + doc.getDate("dateOfDeath"));

    doc.getList("novels", Document.class).forEach((novel) -> {
        System.out.println("title: " + novel.getString("title")
            + ", yearPublished: " + novel.getInteger("yearPublished"));
        });
}

Tip:

The preceding code sample uses helper methods that check the returned type and throw an exception if it is unable to cast the field value. You can call the get() method specified by the Map interface to retrieve field values as type Object and to skip type checking.

The output of the preceding code resembles the following:

_id: 5fb5fad05f734e3794741a35, name: Gabriel García Márquez, dateOfDeath: Thu Apr 17 00:00:00 EDT 2014
title: One Hundred Years of Solitude, yearPublished: 1967
title: Chronicle of a Death Foretold, yearPublished: 1981
title: Love in the Time of Cholera, yearPublished: 1985

For more information about retrieving and manipulating MongoDB data, see our [CRUD guide.](https://www.mongodb.com/docs/drivers/java/sync/current/crud/insert.md#std-label-java-crud-operations

For more information about the methods and classes mentioned in this section, see the following API Documentation:

  • Document

  • [getCollection()](https://mongodb.github.io/mongo-java-driver/5.13/apidocs/driver-sync/com/mongodb/client/MongoDatabase.html#getCollection(java.lang.String)

  • [get()](https://mongodb.github.io/mongo-java-driver/5.13/apidocs/bson/org/bson/Document.html#get(java.lang.Object)

BsonDocument

The BsonDocument class provides a type-safe API to access and manipulate a BSON document. You must specify the BSON type from the Java BSON library for each field. See the following table for mappings between frequently-used BSON and Java BSON library types:

BSON type Java BSON library type
Array org.bson.BsonArray
Binary org.bson.BsonBinary
Boolean org.bson.Boolean
Date (long value) org.bson.BsonDateTime
Document org.bson.BsonDocument
Double org.bson.BsonDouble
Int32 org.bson.BsonInt32
Int64 org.bson.BsonInt64
Null org.bson.BsonNull
ObjectId org.bson.BsonObjectId
String org.bson.BsonString

In the following code snippet, we show how to instantiate and build a sample BsonDocument instance representing a document containing several different field types:

BsonDocument author = new BsonDocument()
    .append("_id", new BsonObjectId())
    .append("name", new BsonString("Gabriel García Márquez"))
    .append("dateOfDeath",
            new BsonDateTime(LocalDate.of(2014, 4, 17).atStartOfDay(ZoneId.systemDefault())
                                                      .toInstant().toEpochMilli()))
    .append("novels", new BsonArray(Arrays.asList(
        new BsonDocument().append("title", new BsonString("One Hundred Years of Solitude"))
                          .append("yearPublished", new BsonInt32(1967)),
        new BsonDocument().append("title", new BsonString("Chronicle of a Death Foretold"))
                          .append("yearPublished", new BsonInt32(1981)),
        new BsonDocument().append("title", new BsonString("Love in the Time of Cholera"))
                          .append("yearPublished", new BsonInt32(1985))
   )));

To insert this document into a collection, instantiate a collection using the getCollection() method specifying the BsonDocument class as the documentClass parameter. Then, call the [insertOne](https://www.mongodb.com/docs/drivers/java/sync/current/crud/insert.md#std-label-java-insertone operation as follows:

// MongoClient mongoClient = <code to instantiate your client>;

MongoDatabase database = mongoClient.getDatabase("fundamentals_data");
MongoCollection<BsonDocument> collection = database.getCollection("authors", BsonDocument.class);

InsertOneResult result = collection.insertOne(author);

Once you perform a successful insert, you can retrieve the sample document data from the collection using the following code:

import com.mongodb.client.model.Filters;

// <MongoCollection setup code here>

BsonDocument doc = collection.find(Filters.eq("name", "Gabriel García Márquez")).first();
if (doc != null) {
    System.out.println("_id: " + doc.getObjectId("_id").getValue()
            + ", name: " + doc.getString("name").getValue()
            + ", dateOfDeath: " + new Date(doc.getDateTime("dateOfDeath").getValue()));

    doc.getArray("novels").forEach((novel) -> {
        System.out.println("title: " + novel.asDocument().getString("title").getValue()
                + ", yearPublished: " + novel.asDocument().getInt32("yearPublished").getValue());
    });
}

Tip:

The preceding code sample uses helper methods that check the returned type and throw a BsonInvalidOperationException if it is unable to cast the field value. You can call the get() method specified by the Map interface to retrieve field values as type BsonValue and to skip type checking.

The output of the preceding code resembles the following:

_id: 5fb5fad05f734e3794741a35, name: Gabriel García Márquez, dateOfDeath: Thu Apr 17 00:00:00 EDT 2014
title: One Hundred Years of Solitude, yearPublished: 1967
title: Chronicle of a Death Foretold, yearPublished: 1981
title: Love in the Time of Cholera, yearPublished: 1985

For more information about the methods and classes mentioned in this section, see the following API Documentation:

  • BsonDocument

  • [getCollection()](https://mongodb.github.io/mongo-java-driver/5.13/apidocs/driver-sync/com/mongodb/client/MongoDatabase.html#getCollection(java.lang.String)

  • BsonInvalidOperationException

  • [get()](https://mongodb.github.io/mongo-java-driver/5.13/apidocs/bson/org/bson/BsonDocument.html#get(java.lang.Object)

  • BsonValue

JsonObject

The JsonObject class acts as a wrapper for JSON strings. If you only want to work with JSON data, you can use JsonObject to avoid unnecessary data conversion to a Map object.

By default, JsonObject stores Extended JSON. You can customize the format of JSON in JsonObject by specifying a JsonObjectCodec and passing it a JsonWriterSettings object. For more information about JSON formats, see our [Extended JSON guide](https://www.mongodb.com/docs/drivers/java/sync/current/data-formats/document-data-format-extended-json.md#std-label-java-extended-json. For more information about specifying codecs, see our [Codecs guide.](https://www.mongodb.com/docs/drivers/java/sync/current/data-formats/codecs.md#std-label-fundamentals-codecs

In the following code snippet, we show how to instantiate a sample JsonObject instance wrapping an Extended JSON string containing different types of key value pairs:

String ejsonStr = "{\"_id\": {\"$oid\": \"6035210f35bd203721c3eab8\"},"
        + "\"name\": \"Gabriel Garc\\u00eda M\\u00e1rquez\","
        + "\"dateOfDeath\": {\"$date\": \"2014-04-17T04:00:00Z\"},"
        + "\"novels\": ["
        + "{\"title\": \"One Hundred Years of Solitude\",\"yearPublished\": 1967},"
        + "{\"title\": \"Chronicle of a Death Foretold\",\"yearPublished\": 1981},"
        + "{\"title\": \"Love in the Time of Cholera\",\"yearPublished\": 1985}]}";
JsonObject author = new JsonObject(ejsonStr);

To insert this document into a collection, instantiate a collection using the getCollection() method specifying the JsonObject class as the documentClass parameter. Then, call the [insertOne](https://www.mongodb.com/docs/drivers/java/sync/current/crud/insert.md#std-label-java-insertone operation as follows:

// MongoClient mongoClient = <code to instantiate your client>;

MongoDatabase database = mongoClient.getDatabase("fundamentals_data");
MongoCollection<JsonObject> collection = database.getCollection("authors", JsonObject.class);

InsertOneResult result = collection.insertOne(author);

Once you perform a successful insert, you can retrieve the sample JSON data from the collection. While you can use any class that extends Bson to specify your query, here is how to query your data using a JsonObject:

// MongoClient mongoClient = <code to instantiate your client>;

JsonObject query = new JsonObject("{\"name\": \"Gabriel Garc\\u00eda M\\u00e1rquez\"}");
JsonObject jsonResult = collection.find(query).first();
if (jsonResult != null) {
    System.out.println("query result in extended json format: " + jsonResult.getJson());
}

The output of the preceding code resembles the following:

query result in extended json format: {"_id": {"$oid": "6035210f35bd203721c3eab8"},
"name": "Gabriel García Márquez", "dateOfDeath": {"$date": "2014-04-17T04:00:00Z"},
"novels": [{"title": "One Hundred Years of Solitude", "yearPublished": 1967},
{"title": "Chronicle of a Death Foretold", "yearPublished": 1981},
{"title": "Love in the Time of Cholera", "yearPublished": 1985}]}

Tip:

If you would like to work with other formats of JSON strings in your application, you can use the JsonObjectCodec class along with JsonWriterSettings to specify your desired JSON format.

The following code example reads and writes to our MongoDB instance using Relaxed mode JSON strings and outputs ObjectId instances as hex strings:

import static org.bson.codecs.configuration.CodecRegistries.fromCodecs;

// MongoClient mongoClient = <code to instantiate your client>;

MongoDatabase database = mongoClient.getDatabase("fundamentals_data");
MongoCollection<JsonObject> collection = database.getCollection("authors", JsonObject.class)
        .withCodecRegistry(
                fromCodecs(
                        // define a JsonObjectCodec with a JsonWriterSettings in Relaxed mode
                        new JsonObjectCodec(JsonWriterSettings
                                .builder()
                                .outputMode(JsonMode.RELAXED)
                                .objectIdConverter((objectId, strictJsonWriter) -> {
                                    strictJsonWriter.writeString(objectId.toHexString());
                                })
                                .build())));
JsonObject author = new JsonObject("{\"_id\": \"6035210f35bd203721c3eab8\", "
        + "\"name\": \"Gabriel García Márquez\", "
        + "\"dateOfDeath\": {\"$date\": \"2014-04-17T04:00:00Z\"}, "
        + "\"novels\": [{\"title\": \"One Hundred Years of Solitude\", \"yearPublished\": 1967},
                        {\"title\": \"Chronicle of a Death Foretold\", \"yearPublished\": 1981}, "
        + "{\"title\": \"Love in the Time of Cholera\", \"yearPublished\": 1985}]}\n");
collection.insertOne(author);
JsonObject query = new JsonObject("{\"name\": \"Gabriel Garc\\u00eda M\\u00e1rquez\"}");
JsonObject jsonResult = collection.find(query).first();
if (jsonResult != null) {
    System.out.println("query result in relaxed json format: " + jsonResult.getJson());
}

The output of the preceding code resembles the following:

query result in relaxed json format: {"_id": "6035210f35bd203721c3eab8", "name": "Gabriel García Márquez",
"dateOfDeath": {"$date": "2014-04-17T04:00:00Z"}, "novels": [{"title": "One Hundred Years of Solitude",
"yearPublished": 1967}, {"title": "Chronicle of a Death Foretold", "yearPublished": 1981},
{"title": "Love in the Time of Cholera", "yearPublished": 1985}]}

For more information about the methods and classes mentioned in this section, see the following API Documentation:

  • JsonObject

  • JsonObjectCodec

  • JsonWriterSettings

  • [getCollection()](https://mongodb.github.io/mongo-java-driver/5.13/apidocs/driver-sync/com/mongodb/client/MongoDatabase.html#getCollection(java.lang.String,java.lang.Class)

Warning: Validate Untrusted Input Before Converting JSON to BSON

If you convert a JSON string to BSON and use the resulting BSON in a query, update, or command, an attacker can inject operators or unexpected field values that change the meaning of the operation. This risk is greatest when the JSON originates from a user, an API request, or another untrusted source.

To learn more about validating input before conversion, see [Validate Untrusted Input Before Converting JSON to BSON.](https://www.mongodb.com/docs/drivers/client-libraries-best-practices.md#std-label-best-practices-validate-json-bson-input

BasicDBObject

The BasicDBObject class allows you to access and manipulate document data using Java types. We recommend that you avoid using this class unless you are migrating an application from an older driver version because of the following limitations:

  • BasicDBObject does not implement Map<K, V> and therefore lacks the data access and manipulation convenience methods of a Map.

  • It implements the DBObject interface rather than a class, so you cannot extend the API without breaking [binary compatibility](https://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.2. This means that if the interface was ever changed in a way that broke the binary compatibility, all applications and classes that use the interface must be recompiled to run the new version without errors.

In the following code snippet, we show how to instantiate and build a sample BasicDBObject instance representing a document containing several different field types:

BasicDBObject author = new BasicDBObject("_id", new ObjectId())
    .append("name", "Gabriel García Márquez")
    .append("dateOfDeath", Date.from(LocalDate.of(2014, 4, 17)
                               .atStartOfDay(ZoneId.systemDefault()).toInstant()))
    .append("novels", Arrays.asList(
        new BasicDBObject("title", "One Hundred Years of Solitude")
            .append("yearPublished", 1967),
        new BasicDBObject("title", "Chronicle of a Death Foretold")
            .append("yearPublished", 1981),
        new BasicDBObject("title", "Love in the Time of Cholera")
            .append("yearPublished", 1985)));

To insert this document into a collection, instantiate a collection using the getCollection() method specifying the BasicDBObject class as the documentClass parameter. Then, call the [insertOne](https://www.mongodb.com/docs/drivers/java/sync/current/crud/insert.md#std-label-java-insertone operation as follows:

// MongoClient mongoClient = <code to instantiate your client>;

MongoDatabase database = mongoClient.getDatabase("fundamentals_data");
MongoCollection<BasicDBObject> collection = database.getCollection("authors", BasicDBObject.class);

InsertOneResult result = collection.insertOne(author);

Once you perform a successful insert, you can retrieve the sample document data from the collection using the following code:

import com.mongodb.client.model.Filters;
// <MongoCollection setup code here>

BasicDBObject doc =
    collection.find(Filters.eq("name", "Gabriel García Márquez")).first();
if (doc != null) {
    System.out.println("_id: " + doc.getObjectId("_id")
        + ", name: " + doc.getString("name")
        + ", dateOfDeath: " + doc.getDate("dateOfDeath"));

    BasicDBList novels = (BasicDBList) doc.get("novels");
    if (novels != null) {
        BasicDBObject[] novelArr = novels.toArray(new BasicDBObject[0]);
        for (BasicDBObject novel : novelArr) {
            System.out.println("title: " + novel.getString("title")
            + ", yearPublished: " + novel.getInt("yearPublished"));
        }
    }
}

Tip:

The preceding code sample uses helper methods that check the returned type and throw an exception if it is unable to cast the field value. You can call the get() method to retrieve values as type Object and to skip type checking.

The output of the preceding code resembles the following:

_id: 5fb5fad05f734e3794741a35, name: Gabriel García Márquez, dateOfDeath: Thu Apr 17 00:00:00 EDT 2014
title: One Hundred Years of Solitude, yearPublished: 1967
title: Chronicle of a Death Foretold, yearPublished: 1981
title: Love in the Time of Cholera, yearPublished: 1985

For more information about the methods and classes mentioned in this section, see the following API Documentation:

  • BasicDBObject

  • [getCollection()](https://mongodb.github.io/mongo-java-driver/5.13/apidocs/driver-sync/com/mongodb/client/MongoDatabase.html#getCollection(java.lang.String,java.lang.Class)

  • [get()](https://mongodb.github.io/mongo-java-driver/5.13/apidocs/bson/org/bson/BasicBSONObject.html?is-external=true#get(java.lang.String)

Summary

In this guide, we covered the following topics on classes you can use to work with BSON data:

  • Described four Java classes you can use to work with MongoDB documents and why you might prefer one over the other.

  • Provided usage examples for each class on building documents containing multiple types, inserting them into a collection, and retrieving/accessing their typed fields.