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

文档数据格式:扩展 JSON

本页内容

  • 概述
  • 扩展 JSON 格式
  • 扩展 JSON 示例
  • 读取扩展 JSON
  • 使用文档类
  • 使用 BSON 库
  • 编写扩展 JSON
  • 使用文档类
  • 使用 BSON 库
  • 自定义 BSON 类型转换

在本指南中,您可以学习如何在 MongoDB Java 驱动程序中使用扩展 JSON 格式。

JSON 是一种数据格式,用于表示对象、数组、数字、字符串、布尔值和 null 的值。扩展 JSON 格式定义了一组保留键,这些键以 "$" 前缀开头,用于表示字段类型信息,这些信息直接对应于 BSON 中的每个类型,BSON 是 MongoDB 用于存储数据的一种格式。$ 表示字段类型信息,这些信息直接对应于 BSON 中的每个类型,BSON 是 MongoDB 用于存储数据的一种格式。

本指南解释了以下主题

  • 不同的 MongoDB 扩展 JSON 格式

  • 如何使用 BSON 库在扩展 JSON 和 Java 对象之间进行转换

  • 如何创建自定义 BSON 类型转换

有关这些格式之间差异的更多信息,请参阅我们的关于 JSON 和 BSON 的文章.

MongoDB 扩展 JSON 功能采用不同的字符串格式来表示 BSON 数据。每种不同的格式都符合 JSON RFC 标准,并满足特定的使用场景。所谓的 扩展 格式,也称为 规范 格式,为每种 BSON 类型提供特定的表示方式,以实现双向转换而不会丢失信息。 宽松模式 格式更加简洁,更接近普通 JSON,但并不表示所有类型信息,例如数字字段的特定字节大小。

请查看以下表格,了解每种格式的描述

名称
描述
扩展
也称为 规范 格式,这种 JSON 表示法避免了 BSON 类型信息的丢失。
此格式以牺牲人类可读性和与旧格式互操作性为代价,优先保留了类型信息。
宽松模式
描述带有一些类型信息损失的 BSON 文档的 JSON 表示法。
此格式以牺牲某些类型信息为代价,优先考虑人类可读性和互操作性。
Shell
与 MongoDB shell 中使用的语法匹配的 JSON 表示法。
此格式优先考虑与 MongoDB shell 的兼容性,MongoDB shell 通常使用 JavaScript 函数来表示类型。
严格
已弃用。 此表示法是符合 JSON RFC 的传统格式,它允许任何 JSON 解析器读取类型信息。
遗留 API 使用此格式。

注意

驱动程序将字符串中的扩展 JSON 类型 $uuid 解析为二进制子类型 4 的 BsonBinary 对象。有关 $uuid 字段解析的更多信息,请参阅扩展 JSON 规范中的解析 $uuid 字段的特殊规则 部分。

有关这些格式的更详细信息,请参阅以下资源

以下示例显示了包含ObjectId、日期和长数字字段的文档,这些字段均以每种扩展JSON格式表示。点击您想查看的示例对应的选项卡

{
"_id": { "$oid": "573a1391f29313caabcd9637" },
"createdAt": { "$date": { "$numberLong": "1601499609" }},
"numViews": { "$numberLong": "36520312" }
}
{
"_id": { "$oid": "573a1391f29313caabcd9637" },
"createdAt": { "$date": "2020-09-30T18:22:51.648Z" },
"numViews": 36520312
}
{
"_id": ObjectId("573a1391f29313caabcd9637"),
"createdAt": ISODate("2020-09-30T18:22:51.648Z"),
"numViews": NumberLong("36520312")
}
{
"_id": { "$oid": "573a1391f29313caabcd9637" },
"createdAt": { "$date": 1601499609 },
"numViews": { "$numberLong": "36520312" }
}

您可以通过调用来自DocumentBsonDocument类的静态parse()方法,将扩展JSON字符串读取到Java文档对象中,具体取决于所需的对象类型。此方法可以解析任何格式的扩展JSON字符串,并返回包含数据的该类的一个实例。

以下示例展示了如何使用Document类通过parse()方法将示例扩展JSON字符串读取到Document对象中。

String ejsonStr = "{ \"_id\": { \"$oid\": \"507f1f77bcf86cd799439011\"}," +
"\"myNumber\": {\"$numberLong\": \"4794261\" }}}";
Document doc = Document.parse(ejsonStr);
System.out.println(doc);
Document{{_id=507f1f77bcf86cd799439011, myNumber=4794261}}

有关更多信息,请参阅我们的基础页面文档.

您还可以使用JsonReader类将扩展JSON字符串读取到Java对象中,而无需使用MongoDB Java驱动程序的文档类。此类包含用于逐个解析扩展JSON字符串中字段和值的方法,并将它们作为Java对象返回。驱动程序的文档类也使用此类来解析扩展JSON。

以下代码示例展示了如何使用JsonReader类将扩展JSON字符串转换为Java对象。

String ejsonStr = "{ \"_id\": { \"$oid\": \"507f1f77bcf86cd799439011\"}," +
"\"myNumber\": {\"$numberLong\": \"4794261\" }}}";
JsonReader jsonReader = new JsonReader(ejsonStr);
jsonReader.readStartDocument();
jsonReader.readName("_id");
ObjectId id = jsonReader.readObjectId();
jsonReader.readName("myNumber");
Long myNumber = jsonReader.readInt64();
jsonReader.readEndDocument();
System.out.println(id + " is type: " + id.getClass().getName());
System.out.println(myNumber + " is type: " + myNumber.getClass().getName());
jsonReader.close();
507f1f77bcf86cd799439011 is type: org.bson.types.ObjectId
4794261 is type: java.lang.Long

有关更多信息,请参阅JsonReader API 文档。

您可以通过调用toJson()方法,从DocumentBsonDocument实例中编写扩展JSON字符串,可选地传递一个JsonWriterSettings实例来指定扩展JSON格式。

在此示例中,我们以宽松模式格式输出扩展JSON。

Document myDoc = new Document();
myDoc.append("_id", new ObjectId("507f1f77bcf86cd799439012")).append("myNumber", 11223344);
JsonWriterSettings settings = JsonWriterSettings.builder().outputMode(JsonMode.RELAXED).build();
System.out.println(doc.toJson(settings));
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "myNumber": 11223344}

您还可以使用BSON库的JsonWriter类从Java对象中的数据输出扩展JSON字符串。要通过JsonWriter构造一个实例,传递一个Java Writer的子类来指定如何输出扩展JSON。您可以可选地传递一个JsonWriterSettings实例来指定选项,例如扩展JSON格式。默认情况下,JsonWriter使用宽松模式格式。MongoDB Java驱动程序的文档类也使用此类将BSON转换为扩展JSON。

以下代码示例展示了如何使用JsonWriter创建扩展JSON字符串并将其输出到System.out。我们通过传递outputMode()构建器方法JsonMode.EXTENDED常量来指定格式

JsonWriterSettings settings = JsonWriterSettings.builder().outputMode(JsonMode.EXTENDED).build();
try (JsonWriter jsonWriter = new JsonWriter(new BufferedWriter(new OutputStreamWriter(System.out)), settings)) {
jsonWriter.writeStartDocument();
jsonWriter.writeObjectId("_id", new ObjectId("507f1f77bcf86cd799439012"));
jsonWriter.writeInt64("myNumber", 11223344);
jsonWriter.writeEndDocument();
jsonWriter.flush();
}
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "myNumber": {"$numberLong": "11223344"}}

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

除了指定 outputMode() 以格式化JSON输出外,您还可以通过向您的 JsonWriterSettings.Builder 中添加转换器来进一步自定义输出。这些转换器方法检测Java类型并执行传递给它们的 Converter 定义的逻辑。

以下示例代码显示了如何将作为lambda表达式定义的转换器附加到简化Relaxed模式JSON输出。

JsonWriterSettings settings = JsonWriterSettings.builder().outputMode(JsonMode.RELAXED)
.objectIdConverter((value, writer) -> writer.writeString(value.toHexString()))
.dateTimeConverter(
(value, writer) -> {
ZonedDateTime zonedDateTime = Instant.ofEpochMilli(value).atZone(ZoneOffset.UTC);
writer.writeString(DateTimeFormatter.ISO_DATE_TIME.format(zonedDateTime));
})
.build();
Document doc = new Document()
.append("_id", new ObjectId("507f1f77bcf86cd799439012"))
.append("createdAt", Date.from(Instant.ofEpochMilli(1601499609000L)))
.append("myNumber", 4794261);
System.out.println(doc.toJson(settings)));

此代码的输出类似于以下文本

{"_id": "507f1f77bcf86cd799439012", "createdAt": "2020-09-30T21:00:09Z", "myNumber": 4794261}

未指定转换器时,Relaxed模式JSON输出类似于以下文本

{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "createdAt": {"$date": "2020-09-30T21:00:09Z"}, "myNumber": 4794261}

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

后退

BSON