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

文档数据格式:扩展 JSON

在此页面上

  • Overview
  • 扩展 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,但并不表示所有类型信息,比如数字字段的具体字节大小等。

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

名称
说明
扩展
Also known as the canonical format, this JSON representation avoids loss of BSON type information.
This format prioritizes type preservation at the loss of human-readability and interoperability with older formats.
宽松模式
JSON representation that describes BSON documents with some type information loss.
This format prioritizes human-readability and interoperability at the loss of certain type information.
Shell
JSON representation that matches the syntax used in the MongoDB shell.
This format prioritizes compatibility with the MongoDB shell which often uses JavaScript functions to represent types.
严格
Deprecated. This representation is the legacy format that fully conforms to the JSON RFC which allows any JSON parser to read the type information.
The legacy API uses this format.

注意

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

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

以下示例显示了包含对象标识符、日期和长数字字段的文档,这些字段分别以扩展 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 使用宽松 (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();
}
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "myNumber": {"$numberLong": "11223344"}}

有关本节中提到的方法和类的详情,请参阅以下 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