Overview
En esta guía, puedes aprender cómo usar los documentos en el MongoDB Java Driver.
Un documento de MongoDB es una estructura de datos que contiene campos clave/valor en formato binario JSON (BSON). Puede usar documentos y los datos que contienen en sus campos para almacenar datos, así como emitir comandos o consultas en MongoDB.
Para más información sobre la terminología, estructura y limitaciones de los documentos, consulta nuestra página sobre Documentos en el manual de MongoDB.
El driver Java de MongoDB y la librería BSON incluyen las siguientes clases que ayudan a acceder y manipular los datos BSON en documentos:
Nombre | Paquete | Implementa Map | Uso recomendado |
|---|---|---|---|
|
| Sí, implementa | Cuando se desea una representación de datos flexible y concisa. |
|
| Sí, implementa | Cuando se requiere una API type-safe. |
|
| No | Cuando solo deseas trabajar con strings JSON. |
|
| No | Cuando migre su aplicación desde una versión de controlador heredada. |
Aunque puedes usar cualquiera de estas clases en tu aplicación, te recomendamos usar la clase Document, ya que puede representar de manera concisa documentos de estructuras dinámicas de cualquier complejidad. Implementa la interfaz Map<String, Object> que le permite usar valores de tipado libre.
Documento
La clase Document ofrece una representación flexible de un documento BSON. Puede acceder y manipular campos utilizando tipos de Java de la librería estándar con esta clase. Consulte la siguiente tabla para ver los mapeos entre los tipos BSON y Java más utilizados:
Tipo BSON | Tipo de Java |
|---|---|
Arreglo |
|
Binario |
|
Booleano |
|
fecha |
|
Documento |
|
Double |
|
Int32 |
|
Int64 |
|
Nulo |
|
ObjectId |
|
String |
|
La tabla de asignaciones precedente muestra la asignación por defecto al trabajar con la clase Document. Puedes personalizar el mapeo de tipos especificando un códec personalizado. Para obtener más información sobre cómo personalizar los tipos mapeados, consulta nuestra guía sobre el uso de Códecs.
En el siguiente fragmento de código, mostramos cómo instanciar y compilar una muestra de instancia de Document que representa un documento que contiene varios tipos de campos diferentes:
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)));
Para insertar este documento en una colección, instancie una colección utilizando el método getCollection() y llame a la operación insertOne de la siguiente manera:
// MongoClient mongoClient = <code to instantiate your client>; MongoDatabase database = mongoClient.getDatabase("fundamentals_data"); MongoCollection<Document> collection = database.getCollection("authors"); InsertOneResult result = collection.insertOne(author);
Una vez que realices una inserción exitosa, puedes recuperar los datos del documento de muestra de la colección usando el siguiente código:
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
La precedente muestra de código utiliza métodos asistentes que verifican el tipo devuelto y lanzan una excepción si no puede convertir el valor del campo. Puedes llamar al método get() especificado por la interfaz Map para recuperar los valores de los campos como tipo Object y omitir la comprobación de tipo.
El resultado del código anterior se asemeja al siguiente:
_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
Para más información sobre cómo recuperar y manipular datos en MongoDB, consulta nuestra guía CRUD.
Para obtener más información sobre los métodos y clases mencionados en esta sección, consulte la siguiente documentación de la API:
BsonDocument
La clase BsonDocument proporciona una API con tipado seguro para acceder y manipular un documento BSON. Se debe especificar el tipo BSON desde la librería BSON de Java para cada campo. Consulta la siguiente tabla para conocer las correlaciones entre los tipos de BSON más utilizados y los de la librería Java BSON:
Tipo BSON | Tipo de librería BSON de Java |
|---|---|
Arreglo |
|
Binario |
|
Booleano |
|
Fecha (valor largo) |
|
Documento |
|
Double |
|
Int32 |
|
Int64 |
|
Nulo |
|
ObjectId |
|
String |
|
En el siguiente fragmento de código, mostramos cómo instanciar y compilar una muestra de instancia de BsonDocument que representa un documento que contiene varios tipos de campos diferentes:
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)) )));
Para insertar este documento en una colección, instancia una colección utilizando el método getCollection() especificando la clase BsonDocument como el parámetro documentClass. Luego, llama a la operación insertOne de la siguiente manera:
// 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);
Una vez que realices una inserción exitosa, puedes recuperar los datos del documento de muestra de la colección usando el siguiente código:
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
La muestra de código precedente utiliza métodos asistentes que verifican el tipo devuelto y lanzan un BsonInvalidOperationException si no pueden convertir el valor del campo. Puedes llamar al método get() especificado por la interfaz Map para recuperar los valores de los campos como tipo BsonValue y omitir la comprobación de tipo.
El resultado del código anterior se asemeja al siguiente:
_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
Para obtener más información sobre los métodos y clases mencionados en esta sección, consulte la siguiente documentación de la API:
JsonObject
La clase JsonObject actúa como un contenedor para cadenas JSON. Si solo quieres trabajar con datos JSON, puedes usar JsonObject para evitar una conversión innecesaria de datos a un objeto Map.
Por defecto, JsonObject almacena JSON extendido. Puedes personalizar el formato de JSON en JsonObject especificando un JsonObjectCodec y pasando un objeto JsonWriterSettings. Para obtener más información sobre los formatos JSON, consulte nuestra Guía extendida de JSON. Para obtener más información sobre cómo especificar códecs, consulta nuestra Guía de códecs.
En el siguiente snippet de código, mostramos cómo instanciar una muestra de JsonObject instancia que envuelve una cadena de JSON extendido que contiene diferentes tipos de pares clave-valor:
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);
Para insertar este documento en una colección, instancia una colección utilizando el método getCollection() especificando la clase JsonObject como el parámetro documentClass. Luego, llama a la operación insertOne de la siguiente manera:
// 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);
Una vez que realice una inserción exitosa, puede recuperar los datos de muestra JSON de la colección. Si bien puedes usar cualquier clase que extienda Bson para especificar tu query, aquí te mostramos cómo consultar tus datos usando un 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()); }
El resultado del código anterior se asemeja al siguiente:
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
Si desea trabajar con otros formatos de cadenas JSON en su aplicación, puede usar la clase JsonObjectCodec junto con JsonWriterSettings para especificar el formato JSON que desea.
El siguiente ejemplo de código lee y escribe en nuestra instancia de MongoDB utilizando cadenas JSON en modo relajado y saca instancias ObjectId como cadenas hexadecimales:
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()); }
El resultado del código anterior se asemeja al siguiente:
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}]}
Para obtener más información sobre los métodos y clases mencionados en esta sección, consulte la siguiente documentación de la API:
BasicDBObject
La clase BasicDBObject te permite acceder y manipular datos de documentos usando tipos de Java. Recomendamos evitar el uso de esta clase a menos que esté migrando una aplicación desde una versión anterior del controlador debido a las siguientes limitaciones:
BasicDBObjectno implementaMap<K, V>y, por tanto, carece de los métodos sencillos de acceso y manipulación de datos de unMap.Implementa la interfaz
DBObjecten lugar de una clase, por lo que no se puede ampliar la API sin romper la compatibilidad binaria. Esto significa que, si la interfaz alguna vez se modificara de manera que se rompiera la compatibilidad binaria, todas las aplicaciones y clases que utilicen la interfaz deben ser recompiladas para ejecutar la nueva versión sin errores.
En el siguiente fragmento de código, mostramos cómo instanciar y compilar una muestra de instancia de BasicDBObject que representa un documento que contiene varios tipos de campos diferentes:
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)));
Para insertar este documento en una colección, instancia una colección utilizando el método getCollection() especificando la clase BasicDBObject como el parámetro documentClass. Luego, llama a la operación insertOne de la siguiente manera:
// 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);
Una vez que realices una inserción exitosa, puedes recuperar los datos del documento de muestra de la colección usando el siguiente código:
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
El código de muestra anterior utiliza métodos de asistente que comprueban el tipo devuelto y lanzan una excepción si no puede convertir el valor del campo. Puedes llamar al método get() para recuperar valores como tipo Object y omitir la comprobación de tipo.
El resultado del código anterior se asemeja al siguiente:
_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
Para obtener más información sobre los métodos y clases mencionados en esta sección, consulte la siguiente documentación de la API:
Resumen
En esta guía, cubrimos los siguientes temas sobre las clases que puedes usar para trabajar con datos BSON:
Describe cuatro clases de Java que se pueden usar para trabajar con documentos MongoDB y por qué se podría preferir una sobre otra.
Se proporcionan ejemplos de uso para cada clase sobre cómo construir documentos que contienen varios tipos, insertarlos en una colección y recuperar/acceder a sus campos tipados.