Overview
JSON是一种数据格式,可表示对象值、数组值、数字值、字符串值、布尔值和空值。扩展JSON格式定义了一设立以 $ 字符为前缀的保留键,用于表示直接对应于BSON中每种类型的字段类型信息,BSON 是MongoDB用于存储数据的格式。
扩展 JSON 格式
MongoDB扩展JSON采用不同的字符串格式来表示BSON数据。 每种格式都符合JSON RFC 并满足特定使用案例。
扩展格式也称为规范格式,为每个BSON类型提供特定表示形式,可进行双向转换而不会丢失信息。Relaxed 格式更加简洁,更接近普通JSON,但并不表示所有类型信息,例如数字字段的具体字节大小等。
下表提供了JSON格式的描述:
名称 | 说明 |
|---|---|
扩展 | 这种 JSON 表示形式也称为规范格式,可以避免丢失 BSON 类型信息。 |
宽松模式 | JSON表示形式,用于描述丢失某些类型信息的BSON文档。 |
Shell | 与 MongoDB shell 中使用的语法相匹配的 JSON 表示。 |
严格 | 已弃用 这种表示形式是完全符合 JSON RFC 的旧版格式,允许任何 JSON 解析器读取类型信息。 |
要学习;了解有关JSON、 BSON和 扩展JSON的更多信息,请参阅我们关于JSON和BSON 的文章以及MongoDB Server手册中的扩展JSON参考。
扩展 JSON 示例
以下标签页显示的文档包含以每种扩展JSON格式表示的 ObjectId、日期和长数字字段。从标签页中进行选择,以查看以每种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" } }
读取扩展 JSON
您可以通过调用 bson.UnmarshalExtJSON() 方法将扩展JSON字符串读入Go结构体。 此方法解析扩展JSON字符串并将结果存储在指定的值参数中。
此示例展示了如何将扩展JSON字符串读入以下 Person 结构:
type Person struct { ID bson.ObjectID `bson:"_id"` Name string Age int Birthday bson.DateTime Address Address Hobbies []string } type Address struct { Street string City string State string }
以下代码使用 UnmarshalExtJSON() 方法读取扩展JSON字符串并将数据解组到 Person实例中:
var extJsonString = "{\"_id\":{\"$oid\":\"578f6fa2df35c7fbdbaed8c5\"},\"name\":\"Liana Ruiz\",\"age\":46,\"birthday\":{\"$date\":\"1988-01-15T00:00:00Z\"},\"address\":{\"street\":\"500 Slippery Rock Road\",\"city\":\"Round Rock\",\"state\":\"AR\"},\"hobbies\":[\"cycling\", \"baking\"]}" var p Person err := bson.UnmarshalExtJSON([]byte(extJsonString), false, &p) if err != nil { log.Fatal(err) } fmt.Printf("Go Struct Representation:\n%+v\n", p)
警告
在将 JSON 转换为 BSON 之前验证不受信任的输入
如果将 JSON string 转换为 BSON 并在查询、更新或命令中使用生成的 BSON,攻击者可以注入操作符或意外的字段值,从而改变操作的含义。当 JSON 来源于用户、API 请求或其他不可信的来源时,这种风险最大。
要了解有关在转换前验证输入的更多信息,请参阅 在将 JSON 转换为 BSON 之前验证不受信任的输入。
写入扩展 JSON
您可以通过调用 bson.MarshalExtJSON() 方法从Go结构体或BSON文档的实例生成扩展JSON字符串。 以下示例从结构体或BSON文档创建宽松格式的扩展JSON字符串。 选择 Struct 或 bson.D标签页以查看相应的示例:
var person = Person{ ID: bson.NewObjectID(), Name: "Matteo Carisi", Age: 49, Birthday: bson.NewDateTimeFromTime(time.Date(1975, 10, 30, 0, 0, 0, 0, time.UTC)), Address: Address{Street: "14a Corner Court", City: "Springfield", State: "IL"}, Hobbies: []string{"cooking", "birdwatching"}, } newExtJsonStringFromStruct, err := bson.MarshalExtJSON(person, false, true) if err != nil { log.Fatal(err) } fmt.Printf("Extended JSON Representation:\n%s\n", newExtJsonStringFromStruct)
bsonDocument := bson.D{{"hello", "world"}, {"number", 1}} newExtJsonStringFromBson, err := bson.MarshalExtJSON(bsonDocument, false, true) if err != nil { panic(err) } fmt.Printf("Extended JSON Representation:\n%s\n", newExtJsonStringFromBson)
MarshalExtJSON() 的第二个参数确定输出字符串是规范(扩展)格式还是宽松格式。 前面的示例将 false 作为 canonical 参数传递,因此输出为宽松JSON。
注意
大纪元时间之前的日期
当您编组一月 1, 1970, 00:00:00 UTC(大纪元时间)之前的日期值时,它将在宽松JSON中显示为 Unix 时间戳。如果日期在大纪元时间之后,则会以可读日期格式显示。
设置扩展JSON格式
您可以使用 bson.MarshalExtJSONIndent() 方法打印格式化的扩展JSON字符串,其中包括换行符、前缀和缩进。
以下代码使用 MarshalExtJSONIndent() 方法打印上一示例中的JSON字符串,并使用两个空格缩进进行格式化:
formattedString, err := bson.MarshalExtJSONIndent(person, false, true, "", " ") if err != nil { log.Fatal(err) } fmt.Printf("%s\n", formattedString)
API 文档
要了解有关本指南中使用的方法和类型的更多信息,请参阅以下 API 文档: