“文档” 菜单
文档首页
/ / /
Java (Sync) 驱动程序
/ /

文档数据格式:扩展 JSON

在此页面上

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

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

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

本指南解释了以下主题:

  • 不同的 MongoDB 扩展 JSON 格式

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

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

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

MongoDB 扩展 JSON 采用不同的字符串格式来表示 BSON 数据。每种不同的格式都符合 JSON RFC 并满足特定的用例。扩展格式也称为规范格式,使得每个 BSON 类型都具有特定表示形式,可进行双向转换而不会丢失信息。宽松模式格式更加简洁,更接近普通 JSON,但并不表示所有类型信息,比如数字字段的具体字节大小等。

请参阅下表查看每种格式的说明:

名称
说明
扩展
这种 JSON 表示形式也称为规范格式,可以避免丢失 BSON 类型信息。
这种格式优先考虑类型保存,但会牺牲人类可读性以及与旧格式的互操作性。
宽松模式
一种 JSON 表示形式,描述了丢失某些类型信息的 BSON 文档。
这种格式优先考虑人类可读性和互操作性,但会丢失某些类型的信息。
Shell
与 MongoDB Shell 中使用的语法相匹配的 JSON 表示。
这种格式优先考虑与 MongoDB Shell 的兼容性,后者通常使用 JavaScript 函数来表示类型。
严格
已弃用。 这种表示形式是完全符合 JSON RFC 它允许任何 JSON 解析器读取类型信息。
旧版 API 使用此格式。

注意

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

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

以下示例显示了包含对象标识符、日期和长数字字段的文档,这些字段分别以扩展 JSON 格式表示。单击与要查看的示例格式相对应的选项卡:

您可以通过从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);

有关更多信息,请参阅有关文档的“基础知识”页面。

您还可以使用 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();

有关更多信息,请参阅 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));

您还可以使用 BSON 库和JsonWriter类从 Java 对象中的数据输出扩展 JSON 字符串。要构造 JsonWriter 实例,请传递 Java Writer的子类以指定希望如何输出扩展 JSON。您可以选择传递一个 JsonWriterSettings 实例来指定扩展 JSON 格式等选项。默认情况下,JsonWriter 使用宽松 (Relaxed) 模式格式。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();
}

有关本节中提到的方法和类的详情,请参阅以下 API 文档:

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

以下示例代码演示如何追加定义为 lambda 表达式的转换器,以简化宽松模式 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}

如果不指定转换器,宽松模式 JSON 输出将类似于以下文本:

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

有关本节中提到的方法和类的详情,请参阅以下 API 文档:

← 文档数据格式:BSON