Docs 菜单
Docs 主页
/ / /
Java (Sync) 驱动程序
/ /

文档 (Document)

在此页面上

  • Overview
  • 文档
  • BsonDocument
  • JsonObject
  • BasicDBObject
  • 总结

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

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

有关文档的术语、结构和限制的更多信息,请参阅MongoDB手册中的文档页面。

MongoDB Java 驱动程序和 BSON 库包含以下类,可帮助您访问和操作文档中的 BSON 数据:

名称
安装包
实施地图
推荐用法
Document
org.bson
是,实现 Map<String, Object>
当您需要灵活简洁的数据表示时。
BsonDocument
org.bson
是,实现 Map<String, BsonValue>
当您需要类型安全的 API 时。
JsonObject
org.bson.json
No
当您只想处理 JSON 字符串时。
BasicDBObject
com.mongodb
No
通过旧版驱动程序版本迁移应用程序时。

虽然您可以在应用程序中使用其中任何类,但我们建议您使用 Document 类,因为其可以简明地表示任何复杂程度的动态结构文档。其实现了 Map<String, Object> 接口,从而可以使用松散类型值。

Document 类可灵活地表示 BSON 文档。通过该类,您可以使用标准库中的 Java 类型访问和操作字段。有关常用 BSON 和 Java 类型之间的映射关系,请参阅下表:

BSON 类型
Java 类型
阵列
java.util.List
二进制文件
org.bson.types.Binary
布尔
java.lang.Boolean
Date
java.util.Date
文档
org.bson.Document
double
java.lang.Double
Int32
java.lang.Integer
Int64
java.lang.Long
null
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 文档:

  • 文档

  • getCollection()

  • get()

BsonDocument类提供类型安全的 API 来访问和操作 BSON 文档。 您必须为每个字段指定 Java BSON 库中的 BSON 类型。 常用 BSON 和 Java BSON 库类型之间的映射关系如下表所示:

BSON 类型
Java BSON 库类型
阵列
org.bson.BsonArray
二进制文件
org.bson.BsonBinary
布尔
org.bson.Boolean
日期(长值)
org.bson.BsonDateTime
文档
org.bson.BsonDocument
double
org.bson.BsonDouble
Int32
org.bson.BsonInt32
Int64
org.bson.BsonInt64
null
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 。 您可以在JsonObject中自定义JSON格式,方法是指定JsonObjectCodec并向其传递JsonWriterSettings对象。 有关JSON格式的更多信息,请参阅我们的扩展JSON指南。 有关指定编解码器的更多信息,请参阅我们的编解码器指南。

在以下代码片段中,我们展示了如何实例化示例 JsonObject 实例,该实例包装包含不同类型键值对的扩展 JSON 字符串:

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

要将此文档插入到某一集合中,请使用 getCollection() 方法实例化一个集合,而此方法会将 JsonObject 类指定为 documentClass 参数。然后,按以下方法调用 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