Overview
在本指南中,您可以学习;了解在与MongoDB文档交互时如何使用扩展JSON数据格式。
JSON是一种人类可读的数据格式,用于表示对象值、数组、数字、字符串、布尔值和空值。此格式仅支持BSON数据类型的子集,而MongoDB正是使用该格式来存储数据。扩展JSON格式支持更多BSON 类型,定义了一设立以 "$" 为前缀的保留键,用于表示直接对应于BSON中每种类型的字段类型信息。
要学习;了解有关JSON、 BSON和扩展JSON的更多信息,请参阅JSON和BSON资源以及扩展JSON MongoDB Server手册条目。
扩展 JSON 格式
MongoDB扩展JSON提供字符串格式来表示BSON数据。 每种格式都符合JSON RFC 并满足特定的使用案例。
下表描述了每种扩展JSON格式:
名称 | 说明 |
|---|---|
扩展或规范 | A string format that avoids loss of BSON type information during data conversions. |
宽松 | A string format that describes BSON documents with some type information loss. |
Shell | A string format that matches the syntax used in the MongoDB shell. |
注意
Kotlin 同步驱动程序将 $uuid 扩展 JSON 类型从 string 解析为二进制子类型 4 的 Binary 对象。有关 $uuid 字段解析的更多信息,请参阅扩展 JSON 规范中解析 $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") }
读取扩展 JSON
本节介绍如何通过以下方式将扩展JSON值读取到Kotlin对象中:
使用文档类
要将扩展JSON字符串读入Kotlin文档对象,请从 Document 或 BsonDocument 类中调用 parse() 静态方法。 此方法解析扩展JSON字符串并将其数据存储在指定文档类的实例中。
以下示例使用 parse() 方法将扩展JSON字符串读入 Document对象:
val ejsonStr = """ { "_id": { "$${"oid"}": "507f1f77bcf86cd799439011" }, "myNumber": { "$${"numberLong"}": "4794261" } } """.trimIndent() val doc = Document.parse(ejsonStr) println(doc)
使用 JsonReader 类
要在不使用Kotlin Sync驱动程序的文档类的情况下将扩展JSON字符串读入Kotlin对象,请使用BSON库的 JsonReader 类。 此类包含用于按顺序解析扩展JSON字符串的字段和值并将它们作为Kotlin对象返回的方法。 驱动程序的文档类也使用此类来解析 扩展JSON。
以下代码使用 JsonReader 类提供的方法将扩展JSON字符串转换为Kotlin对象:
val string = """ { "_id": { "$${"oid"}": "507f1f77bcf86cd799439011" }, "myNumber": { "$${"numberLong"}": "4794261" } } """.trimIndent() val jsonReader = JsonReader(string) jsonReader.readStartDocument() // Reads the "_id" field value jsonReader.readName("_id") val id = jsonReader.readObjectId() // Reads the "myNumber" field value jsonReader.readName("myNumber") val myNumber = jsonReader.readInt64() jsonReader.readEndDocument() println("$id is type: ${id::class.qualifiedName}") println("$myNumber is type: ${myNumber::class.qualifiedName}") jsonReader.close()
警告
在将JSON转换为BSON之前验证不可信输入
如果将JSON字符串转换为BSON并在查询、 更新或 command 中使用生成的BSON ,则攻击者可以注入操作符或意外的字段值,从而更改操作的含义。当JSON源自用户、 API请求或其他不可信来源时,这种风险最大。
To learn more about validating input before conversion, see Validate Untrusted Input Before Converting JSON to BSON.
写入扩展 JSON
本节介绍如何通过以下方式从Kotlin对象写入扩展JSON值:
使用文档类
要从 Document 或 BsonDocument对象写入扩展JSON字符串,请调用 toJson() 方法。 您可以向此方法传递一个 JsonWriterSettings对象参数,以指定扩展JSON格式。
以下示例将 Document 数据写入为宽松模式扩展JSON:
val doc = Document() .append("_id", ObjectId("507f1f77bcf86cd799439012")) .append("createdAt", Date.from(Instant.ofEpochMilli(1601499609000L))) .append("myNumber", 4794261) val settings = JsonWriterSettings.builder() .outputMode(JsonMode.RELAXED) .build() println(doc.toJson(settings))
使用 JsonWriter 类
要从Kotlin对象中存储的数据输出扩展JSON字符串,您可以使用BSON库的 JsonWriter 类。 要构造 JsonWriter对象,请传递Java Writer 的子类以指定希望如何输出扩展JSON。(可选)您可以传递 JsonWriterSettings实例来指定选项,例如扩展JSON格式。默认下,JsonWriter 使用宽松模式格式。Kotlin Sync驱动程序的文档类也使用此类将BSON转换为扩展JSON。
以下示例使用 JsonWriter对象创建规范模式扩展JSON字符串值并将其输出到 System.out:
val settings = JsonWriterSettings.builder() .outputMode(JsonMode.EXTENDED) .build() JsonWriter(BufferedWriter(OutputStreamWriter(System.out)), settings).use { jsonWriter -> jsonWriter.writeStartDocument() jsonWriter.writeName("_id") jsonWriter.writeObjectId(ObjectId("507f1f77bcf86cd799439012")) jsonWriter.writeName("myNumber") jsonWriter.writeInt64(11223344L) jsonWriter.writeEndDocument() jsonWriter.flush() }
自定义 BSON 类型转换
除了指定扩展JSON输出格式之外,您还可以通过向 JsonWriterSettings对象添加转换器来进一步自定义输出。这些转换器方法指定在转换进程中处理不同数据类型的逻辑。
The following example converts the same document as the Use the Document Classes example. However, this example defines the objectIdConverter() and dateTimeConverter() converter methods in a JsonWriterSettings object to simplify the Relaxed mode Extended JSON output:
val settings = JsonWriterSettings.builder() .outputMode(JsonMode.RELAXED) .objectIdConverter { value, writer -> writer.writeString(value.toHexString()) } .dateTimeConverter { value, writer -> val zonedDateTime = Instant.ofEpochMilli(value).atZone(ZoneOffset.UTC) writer.writeString(DateTimeFormatter.ISO_DATE_TIME.format(zonedDateTime)) } .build() val doc = Document() .append("_id", ObjectId("507f1f77bcf86cd799439012")) .append("createdAt", Date.from(Instant.ofEpochMilli(1601499609000L))) .append("myNumber", 4794261) println(doc.toJson(settings))
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: