Docs 菜单
Docs 主页
/ / /
java sync
/ /

文档 (Document)

在此页面上

  • 概述
  • 文档
  • 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
当您只想处理 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
Date
java.util.Date
文档
org.bson.Document
双精度
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 文档:

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
双精度
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