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)
警告
Validate Untrusted Input Before Converting JSON to BSON
If you convert a JSON string to BSON and use the resulting BSON in a query, update, or command, an attacker can inject operators or unexpected field values that change the meaning of the operation. This risk is greatest when the JSON originates from a user, an API request, or another untrusted source.
To learn more about validating input before conversion, see Validate Untrusted Input Before Converting JSON to 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 文档: