对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

使用扩展JSON数据

在本指南中,您可以学习;了解在与MongoDB文档交互时如何使用扩展JSON数据格式。

JSON是一种人类可读的数据格式,用于表示对象值、数组、数字、字符串、布尔值和空值。此格式仅支持BSON数据类型的子集,而MongoDB正是使用该格式来存储数据。扩展JSON格式支持更多BSON 类型,定义了一设立以 "$" 为前缀的保留键,用于表示直接对应于BSON中每种类型的字段类型信息。

要学习;了解有关JSON、 BSON和扩展JSON的更多信息,请参阅JSON和BSON资源以及扩展JSON MongoDB Server手册条目。

MongoDB扩展JSON提供字符串格式来表示BSON数据。 每种格式都符合JSON RFC 并满足特定的使用案例。

下表描述了每种扩展JSON格式:

名称
说明

扩展规范

一种 string 格式,可避免在数据转换过程中丢失 BSON 类型信息。
这种格式优先考虑类型保存,但会牺牲人类可读性以及与旧格式的互操作性。JsonMode.EXTENDED

宽松

一种 string 格式,用于描述 BSON 文档,但会丢失某些类型信息。
这种格式优先考虑人类可读性和互操作性,但会丢失某些类型信息。JsonMode.RELAXED

Shell

与 MongoDB shell 中使用的语法匹配的 string 格式。
该格式优先考虑与 MongoDB shell 的兼容性,后者通常使用 JavaScript 函数来表示类型。JsonMode.SHELL

解析 $uuid 字段的特殊规则

以下示例显示了包含对象标识符、日期和长数字字段的文档,这些字段分别以扩展 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")
}

您可以使用 Scala 驱动程序的文档类或直接使用 BSON 库将扩展 JSON string 读入 Scala 对象。以下部分展示了如何使用每种方法。

您可以通过在 BsonDocument 上调用 parse() 静态方法,然后将结果包装在 Scala Document 实例中,将扩展 JSON string 读取到 Scala 文档对象中。此方法解析任何格式的扩展 JSON string,并返回包含数据的 Document

以下示例展示了如何通过调用 BsonDocument.parse() 并将结果传递给 Document 工厂来将扩展 JSON string 读取到 Document 对象中:

val ejsonStr = """{"_id": {"$oid": "507f1f77bcf86cd799439011"}, "myNumber": {"$numberLong": "4794261"}}"""
val document = Document(BsonDocument.parse(ejsonStr))
println(document)
Iterable((_id,BsonObjectId{value=507f1f77bcf86cd799439011}), (myNumber,BsonInt64{value=4794261}))

要了解有关 MongoDB 中文档的更多信息,请参阅 MongoDB Server 手册中的文档

您还可以使用 JsonReader 类将扩展 JSON string 读入 Scala 对象,而无需使用 Scala 驱动程序的文档类。此类包含用于按顺序解析扩展 JSON string 任何格式中的字段和值,并将其作为 Scala 对象返回的方法。驱动程序的文档类也使用此类来解析扩展 JSON。

以下代码示例展示如何使用 JsonReader 类将扩展 JSON string 转换为 Scala 对象:

val ejsonStr = """{"_id": {"$oid": "507f1f77bcf86cd799439011"}, "myNumber": {"$numberLong": "4794261"}}"""
val reader = new JsonReader(ejsonStr)
reader.readStartDocument()
val id = reader.readObjectId("_id")
val myNumber = reader.readInt64("myNumber")
reader.readEndDocument()
println(s"$id is type: ${id.getClass.getName}")
println(s"$myNumber is type: ${myNumber.getClass.getName}")
507f1f77bcf86cd799439011 is type: org.bson.types.ObjectId
4794261 is type: long

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

您可以使用 Scala 驱动程序的文档类或直接使用 BSON 库从数据中写入扩展 JSON string。以下部分展示了如何使用每种方法。

您可以通过调用 toJson() 方法从 DocumentBsonDocument 的实例写入扩展JSON字符串。默认下,toJson() 方法以宽松模式格式输出字符串。要使用其他格式,请将 JsonWriterSettings 类的实例传递给 toJson() 方法。

以下示例调用不带参数的 toJson() 方法,以默认宽松模式格式输出扩展 JSON:

val document = Document(
"_id" -> BsonObjectId(new ObjectId("507f1f77bcf86cd799439012")),
"myNumber" -> BsonInt64(11223344L)
)
val ejsonStr = document.toJson()
println(ejsonStr)
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "myNumber": 11223344}

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

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

val writer = new StringWriter()
val jsonWriter = new JsonWriter(writer,
JsonWriterSettings.builder().outputMode(JsonMode.EXTENDED).build())
jsonWriter.writeStartDocument()
jsonWriter.writeObjectId("_id", new ObjectId("507f1f77bcf86cd799439012"))
jsonWriter.writeInt64("myNumber", 11223344L)
jsonWriter.writeEndDocument()
println(writer.toString())
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "myNumber": {"$numberLong": "11223344"}}

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

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

以下示例代码演示如何追加定义为 Lambda 表达式的转换器,以简化宽松模式 JSON 输出:

val settings = JsonWriterSettings.builder()
.outputMode(JsonMode.RELAXED)
.objectIdConverter((value, writer) => writer.writeString(value.toHexString))
.timestampConverter((value, writer) => {
val instant = Instant.ofEpochSecond(value.getTime.toLong)
writer.writeString(
DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneOffset.UTC).format(instant))
})
.build()
val document = Document(
"_id" -> BsonObjectId(new ObjectId("507f1f77bcf86cd799439012")),
"createdAt" -> new BsonTimestamp(1601516589, 1),
"myNumber" -> BsonInt64(4794261L)
)
println(document.toJson(settings))
{"_id": "507f1f77bcf86cd799439012", "createdAt": "2020-10-01T01:43:09", "myNumber": 4794261}
// Without specifying the converters, the Relaxed mode JSON output
// would look something like this:
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "createdAt": {"$timestamp": {"t": 1601516589, "i": 1}}, "myNumber": 4794261}

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