文档菜单
文档首页
/ / /
Java 同步驱动
/ /

文档

本页内容

  • 概述
  • 文档
  • BsonDocument
  • JsonObject
  • BasicDBObject
  • 摘要

在本指南中,您可以学习如何在MongoDB Java驱动程序中使用文档

MongoDB文档是一种包含键/值字段的二进制JSON(BSON)格式的数据结构。您可以使用文档及其字段中的数据来存储数据,以及向MongoDB发布命令或查询。

有关术语、结构和文档的限制的更多信息,请阅读我们关于文档的页面

MongoDB Java驱动程序和BSON库包括以下类,这些类有助于您访问和操作文档中的BSON数据

名称
实现Map
推荐使用
文档
org.bson
是,实现了Map<String, Object>
当您需要灵活且简洁的数据表示时。
BsonDocument
org.bson
是,实现了Map<String, BsonValue>
当您需要类型安全的API时。
JsonObject
org.bson.json
当您只想处理JSON字符串时。
BasicDBObject
com.mongodb
当您正在从旧版驱动程序版本迁移应用程序时。

尽管您可以在应用程序中使用这些类中的任何一个,但我们建议您使用Document类,因为它可以简洁地表示任何复杂性的动态结构化文档。它实现了Map<String, Object>接口,使其能够使用弱类型值。

Document类提供了一个灵活的BSON文档表示。您可以使用此类使用标准库中的Java类型访问和操作字段。以下表格显示了常用的BSON和Java类型之间的映射

BSON类型
Java类型
数组
java.util.List
二进制
org.bson.types.Binary
布尔
java.lang.Boolean
日期
java.util.Date
文档
org.bson.Document
双精度浮点数
java.lang.Double
Int32
java.lang.Integer
Int64
java.lang.Long
空值
null
ObjectId
org.bson.types.ObjectId
字符串
java.lang.String

上述映射表显示了使用Document类时的默认映射。您可以通过指定自定义编解码器来自定义类型映射。有关自定义映射类型的更多信息,请参阅我们关于使用编解码器.

以下代码片段展示了如何实例化和构建一个示例Document实例,该实例表示包含几种不同字段类型的文档

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)));

要将此文档插入集合中,使用getCollection()方法实例化一个集合,并按以下方式调用insertOne操作

// MongoClient mongoClient = <code to instantiate your client>;
MongoDatabase database = mongoClient.getDatabase("fundamentals_data");
MongoCollection<Document> collection = database.getCollection("authors");
InsertOneResult result = collection.insertOne(author);

成功执行插入操作后,您可以使用以下代码从集合中检索示例文档数据:

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"));
});
}

提示

前面的代码示例使用了辅助方法,用于检查返回类型,如果无法将字段值转换为类型,则会抛出异常。您可以通过调用由 Map 接口指定的 get() 方法来检索字段值,并将其作为类型 Object 返回,从而跳过类型检查。

前面代码的输出类似于以下内容

_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

有关检索和操作 MongoDB 数据的更多信息,请参阅我们的 CRUD 指南。

有关本节中提到的方法和类的更多信息,请参阅以下 API 文档

BsonDocument 类提供了一个类型安全的 API,用于访问和操作 BSON 文档。您必须为每个字段指定来自 Java BSON 库的 BSON 类型。以下表格显示了常用 BSON 类型与 Java BSON 库类型之间的映射关系

BSON类型
Java BSON 库类型
数组
org.bson.BsonArray
二进制
org.bson.BsonBinary
布尔
org.bson.Boolean
Date(长整型值)
org.bson.BsonDateTime
文档
org.bson.BsonDocument
双精度浮点数
org.bson.BsonDouble
Int32
org.bson.BsonInt32
Int64
org.bson.BsonInt64
空值
org.bson.BsonNull
ObjectId
org.bson.BsonObjectId
字符串
org.bson.BsonString

在以下代码片段中,我们展示了如何实例化和构建一个表示包含几种不同字段类型的文档的样本 BsonDocument 实例

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))
)));

要将此文档插入到集合中,使用 getCollection() 方法实例化一个集合,指定 BsonDocument 类作为 documentClass 参数。然后,按照以下方式调用 insertOne 操作:

// 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);

成功执行插入操作后,您可以使用以下代码从集合中检索示例文档数据:

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());
});
}

提示

前面的代码示例使用了辅助方法,用于检查返回类型,如果无法将字段值转换为类型,则会抛出 BsonInvalidOperationException。您可以通过调用由 Map 接口指定的 get() 方法来检索字段值,并将其作为类型 BsonValue 返回,从而跳过类型检查。

前面代码的输出类似于以下内容

_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

有关本节中提到的方法和类的更多信息,请参阅以下 API 文档

JsonObject 类充当 JSON 字符串的包装器。如果您只想处理 JSON 数据,则可以使用 JsonObject 以避免将数据不必要地转换为 Map 对象。

默认情况下,JsonObject 存储扩展 JSON。您可以通过指定一个 JsonObjectCodec 并将其传递给一个 JsonWriterSettings 对象来自定义 JsonObject 中的 JSON 格式。有关 JSON 格式的更多信息,请参阅我们的扩展 JSON 指南。有关指定编码器的更多信息,请参阅我们的编码器指南

以下代码片段展示了如何实例化一个包含不同类型键值对的扩展 JSON 字符串的示例 JsonObject 实例。

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);

要将此文档插入集合中,使用指定 JsonObject 类作为 documentClass 参数的 getCollection() 方法创建一个集合。然后,按照以下方式调用 insertOne 操作。

// 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);

一次成功插入后,您可以从集合中检索示例 JSON 数据。虽然您可以使用任何扩展 Bson 的类来指定您的查询,但以下是使用 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());
}

前面代码的输出类似于以下内容

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}]}

提示

如果您希望在应用程序中处理其他格式的 JSON 字符串,则可以使用 JsonObjectCodec 类和 JsonWriterSettings 来指定所需的 JSON 格式。

以下代码示例使用宽松模式 JSON 字符串读取和写入我们的 MongoDB 实例,并以十六进制字符串输出 ObjectId 实例。

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());
}

前面代码的输出类似于以下内容

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}]}

有关本节中提到的方法和类的更多信息,请参阅以下 API 文档

BasicDBObject 类允许您使用 Java 类型访问和操作文档数据。我们建议除非您正在从旧版驱动程序版本迁移应用程序,否则请避免使用此类,因为以下限制:

  • BasicDBObject 没有实现 Map<K, V> 接口,因此缺乏 Map 的数据访问和操作便捷方法。

  • 它实现了 DBObject 接口而不是类,因此您无法在不破坏二进制兼容性的情况下扩展 API。这意味着如果接口因破坏二进制兼容性而进行了更改,则必须重新编译所有使用该接口的应用程序和类,才能在新的版本上无错误地运行。

以下代码示例展示了如何实例化和构建一个表示包含多种不同字段类型的文档的 BasicDBObject 实例。

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)));

要将此文档插入到集合中,使用 getCollection() 方法实例化一个集合,并将 BasicDBObject 类指定为 documentClass 参数。然后,按如下方式调用 insertOne 操作。

// 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);

成功执行插入操作后,您可以使用以下代码从集合中检索示例文档数据:

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"));
}
}
}

提示

前面的代码示例使用了检查返回类型的辅助方法,如果无法将字段值强制转换为类型,则抛出异常。您可以通过调用 get() 方法以 Object 类型检索值并跳过类型检查。

前面代码的输出类似于以下内容

_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

有关本节中提到的方法和类的更多信息,请参阅以下 API 文档

在本指南中,我们介绍了有关使用 BSON 数据的类。

  • 介绍了四个可以用来处理MongoDB文档的Java类,以及为什么你可能更倾向于使用其中一个而不是另一个。

  • 为每个类提供了使用示例,包括构建包含多种类型的文档、将它们插入到集合中以及检索/访问它们的类型字段。

返回

扩展JSON