Overview
在本指南中,您可以学习;了解在与MongoDB文档交互时如何使用扩展JSON数据格式。
JSON是一种人类可读的数据格式,用于表示对象值、数组、数字、字符串、布尔值和空值。此格式仅支持BSON数据类型的子集,而MongoDB正是使用该格式来存储数据。扩展JSON格式支持更多BSON 类型,定义了一设立以 "$" 为前缀的保留键,用于表示直接对应于BSON中每种类型的字段类型信息。
要学习;了解有关JSON、 BSON和扩展JSON的更多信息,请参阅JSON和BSON资源以及扩展JSON MongoDB Server手册条目。
扩展 JSON 格式
MongoDB扩展JSON提供字符串格式来表示BSON数据。 每种格式都符合JSON RFC 并满足特定的使用案例。
下表描述了每种扩展JSON格式:
名称 | 说明 |
|---|---|
扩展或规范 | 一种 string 格式,可避免在数据转换过程中丢失 BSON 类型信息。 |
宽松 | 一种 string 格式,用于描述 BSON 文档,但会丢失某些类型信息。 |
Shell | 与 MongoDB shell 中使用的语法匹配的 string 格式。 |
扩展 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") }
读取扩展 JSON
您可以使用 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 手册中的文档。
BSON 库
您还可以使用 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 文档。
写入扩展 JSON
您可以使用 Scala 驱动程序的文档类或直接使用 BSON 库从数据中写入扩展 JSON string。以下部分展示了如何使用每种方法。
文档类
您可以通过调用 toJson() 方法从 Document 或 BsonDocument 的实例写入扩展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 库
您还可以使用 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 文档:
自定义 BSON 类型转换
除了指定 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 文档: