Documentos
Visão geral
Neste guia, você pode aprender como usar documentos no Driver Java MongoDB.
Um documento do MongoDB é uma estrutura de dados que contém campos de chave/valor no formato JSON binário (BSON). Você pode usar documentos e os dados que eles contêm em seus campos para armazenar dados, bem como para emitir comandos ou queries no MongoDB.
Para obter mais informações sobre a terminologia, estrutura e limitações dos documentos, leia nossa página sobre Documentos no manual do MongoDB.
O driver Java do MongoDB e a biblioteca BSON incluem as seguintes classes que ajudam a acessar e manipular os dados BSON em documentos:
Nome | Pacote | Mapa de implementos | Uso recomendado |
---|---|---|---|
Document | org.bson | Sim, implementa Map<String, Object> | Quando você deseja uma representação de dados flexível e concisa. |
BsonDocument | org.bson | Sim, implementa Map<String, BsonValue> | Quando você precisa de uma API com segurança de tipo. |
JsonObject | org.bson.json | No | Quando você deseja trabalhar somente com strings JSON. |
BasicDBObject | com.mongodb | No | Ao migrar seu aplicativo de uma versão de driver herdada. |
Embora possa usar qualquer uma dessas classes em seu aplicativo, recomendamos utilizar a classe Document
, pois ela representa de forma concisa documentos estruturados dinamicamente de qualquer complexidade. Ela implementa a interface Map<String, Object>
, o que lhe permite usar valores de tipos livres.
Documento
A classe Document
oferece uma representação flexível de um documento BSON. Você pode acessar e manipular campos utilizando tipos Java da biblioteca padrão com esta classe. Consulte a tabela a seguir para mapeamentos entre os tipos BSON e Java usados com frequência:
Tipo de BSON | Tipo de Java |
---|---|
Array | java.util.List |
Binário | org.bson.types.Binary |
Boolean | java.lang.Boolean |
Data | java.util.Date |
Documento | org.bson.Document |
Double | java.lang.Double |
Int32 | java.lang.Integer |
Int64 | java.lang.Long |
Zero | null |
ObjectId | org.bson.types.ObjectId |
String | java.lang.String |
A tabela de mapeamento anterior mostra o mapeamento padrão ao trabalhar com a classe Document
. Você pode personalizar o mapeamento de tipo especificando um codec personalizado. Para obter mais informações sobre como personalizar os tipos mapeados, veja o nosso guia sobre o uso decodecs .
No trecho de código abaixo, mostramos como instanciar e construir uma instância Document
de amostra que representa um documento com vários tipos de campos:
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 inserir esse documento em uma coleção, instancie uma coleção usando o método getCollection()
e chame a operação insertOne da seguinte forma:
// MongoClient mongoClient = <code to instantiate your client>; MongoDatabase database = mongoClient.getDatabase("fundamentals_data"); MongoCollection<Document> collection = database.getCollection("authors"); InsertOneResult result = collection.insertOne(author);
Depois de realizar uma inserção bem-sucedida, você pode recuperar os dados do documento de amostra da coleção usando o código a seguir:
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")); }); }
Dica
O exemplo de código anterior usa métodos auxiliares que verificam o tipo retornado e lançam uma exceção se não for possível converter o valor do campo. Você pode chamar o método get()
especificado pela interface do Map
para recuperar valores de campo como tipo Object
e ignorar a verificação de tipo.
A saída deve ser semelhante a esta:
_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 obter mais informações sobre os métodos e as classes mencionadas nesta seção, consulte a seguinte documentação da API:
Documento BSON
A classe BsonDocument
fornece uma API segura por tipo para acessar e manipular um documento BSON. Você precisa especificar o tipo BSON da biblioteca Java BSON para cada campo. Consulte a tabela a seguir para mapeamentos entre os tipos de biblioteca BSON e Java BSON usados com frequência:
Tipo de BSON | Tipo de biblioteca Java BSON |
---|---|
Array | org.bson.BsonArray |
Binário | org.bson.BsonBinary |
Boolean | org.bson.Boolean |
Data (valor longo) | org.bson.BsonDateTime |
Documento | org.bson.BsonDocument |
Double | org.bson.BsonDouble |
Int32 | org.bson.BsonInt32 |
Int64 | org.bson.BsonInt64 |
Zero | org.bson.BsonNull |
ObjectId | org.bson.BsonObjectId |
String | org.bson.BsonString |
No trecho de código abaixo, mostramos como instanciar e construir uma instância BsonDocument
de amostra que representa um documento com vários tipos de campos:
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 inserir este documento em uma coleção, instancie uma coleção utilizando o método getCollection()
especificando a classe BsonDocument
como o parâmetro documentClass
. Em seguida, ligue para a operação insertOne da seguinte maneira:
// 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);
Depois de realizar uma inserção bem-sucedida, você pode recuperar os dados do documento de amostra da coleção usando o código a seguir:
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()); }); }
Dica
O exemplo de código anterior usa métodos auxiliares que verificam o tipo gerado e lançam um BsonInvalidOperationException
se não for possível converter o valor do campo. Você pode chamar o método get()
especificado pela interface Map
para recuperar valores de campo do tipo BsonValue
e ignorar a verificação de tipo.
A saída deve ser semelhante a esta:
_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 obter mais informações sobre os métodos e as classes mencionadas nesta seção, consulte a seguinte documentação da API:
JsonObject
A classe JsonObject
age como um wrapper para strings JSON. Se você deseja trabalhar somente com dados JSON, use o JsonObject
para evitar uma conversão de dados desnecessária para um objeto Map
.
Por padrão, JsonObject
armazena JSON estendido. Você pode personalizar o formato de JSON no JsonObject
especificando um JsonObjectCodec
e passando um objeto JsonWriterSettings
. Para mais informações sobre formatos JSON, consulte nosso guia JSON estendido. Para obter mais informações sobre como especificar codecs, consulte nosso guia de codecs.
No trecho de código a seguir, mostramos como instanciar uma instância de JsonObject
de exemplo encapsulando uma string JSON estendida contendo diferentes tipos de pares de valores de chave:
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 inserir este documento em uma coleção, instancie uma coleção utilizando o método getCollection()
especificando a classe JsonObject
como o parâmetro documentClass
. Em seguida, ligue para a operação insertOne da seguinte maneira:
// 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);
Após executar uma inserção bem-sucedida, você pode recuperar a amostra de dados JSON da coleção. Enquanto você pode utilizar qualquer classe que estenda o Bson
para especificar sua query, aqui está como executar query de seus dados utilizando um 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()); }
A saída deve ser semelhante a esta:
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}]}
Dica
Se você deseja trabalhar com outros formatos de strings JSON em seu aplicativo, use a classe JsonObjectCodec
junto com JsonWriterSettings
para especificar seu formato JSON desejado.
O exemplo de código a seguir lê e grava em nossa instância do MongoDB usando cadeias de caracteres JSON no modo relaxado e gera instâncias ObjectId
como strings hexadecimais:
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()); }
A saída deste código deve ser semelhante a esta:
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 obter mais informações sobre os métodos e as classes mencionadas nesta seção, consulte a seguinte documentação da API:
Objeto de banco de dados básico
A classe BasicDBObject
permite acessar e manipular dados do documento utilizando tipos Java. Recomendamos não usar essa classe, a menos que você esteja migrando um aplicativo de uma versão de driver mais antiga devido às seguintes limitações:
BasicDBObject
não implementa oMap<K, V>
e, portanto, não tem acesso aos dados e métodos de conveniência de manipulação de umMap
.Ele implementa a interface
DBObject
em vez de uma classe, portanto, você não pode estender a API sem quebrar a compatibilidade binária. Isso significa que, se a interface alguma vez foi alterada de forma a quebrar a compatibilidade binária, todos os aplicativos e classes que usam a interface precisam ser recompilados para executar a nova versão sem erros.
No trecho de código abaixo, mostramos como instanciar e construir uma instância BasicDBObject
de amostra que representa um documento com vários tipos de campos:
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 inserir este documento em uma coleção, instancie uma coleção utilizando o método getCollection()
especificando a classe BasicDBObject
como o parâmetro documentClass
. Em seguida, ligue para a operação insertOne da seguinte maneira:
// 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);
Depois de realizar uma inserção bem-sucedida, você pode recuperar os dados do documento de amostra da coleção usando o código a seguir:
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")); } } }
Dica
O exemplo de código anterior usa métodos auxiliares que verificam o tipo retornado e lançam uma exceção se não for possível converter o valor do campo. Você pode chamar o método get()
para recuperar valores como tipo Object
e ignorar a verificação de tipo.
A saída deve ser semelhante a esta:
_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 obter mais informações sobre os métodos e as classes mencionadas nesta seção, consulte a seguinte documentação da API:
Resumo
Neste guia, descrevemos os seguintes tópicos de classes que você pode usar para trabalhar com dados BSON:
Descreveu quatro classes Java que você pode usar para trabalhar com documentos do MongoDB, e por que uma classe pode ser melhor que a outra.
Fornecer exemplos de uso para cada classe em documentos de construção contendo vários tipos, inserindo-os em uma coleção e recuperando/acessando seus campos digitados.