天天看点

mongodb——MongoDB扩展JSON(v1)

作者:老葛说码

消除歧义

以下讨论MongoDB扩展JSON v1(旧版扩展JSON)。有关MongoDB扩展JSON v2的讨论,请参见MongoDB扩展JSON(v2)。

有关类型的mongo shell包装器方法,请参见mongo shell中的数据类型。

JSON只能表示BSON支持的一部分类型。为了保留类型信息,MongoDB向JSON格式添加以下扩展:

  • 严格模式。 BSON类型的严格模式表示符合JSON RFC。任何JSON解析器都可以将这些严格模式表示解析为键/值对;但是,只有MongoDB内部的JSON解析器才能识别所传达的格式中的类型信息。
  • mongo shell模式。MongoDB内部的JSON解析器和mongo shell可以解析此模式。

用于各种数据类型的表示取决于解析JSON的上下文。

MongoDB扩展JSON v1和MongoDB驱动程序

以下驱动程序使用扩展JSON v1.0(旧版):C#,Ruby

对于其他驱动程序,请参阅MongoDB扩展JSON(v2)。

解析器和支持的格式

严格模式输入

以下工具可以解析严格模式表示,并识别类型信息。

  • Mongoimport版本4.0及早期版本
  • 各种MongoDB工具的--query选项
  • MongoDB Compass

其他JSON解析器,包括mongo shell,可以将严格模式表示解析为键/值对,但无法识别类型信息。

在mongo shell模式下输入

以下工具可以解析mongo shell模式表示,并识别类型信息。

  • Mongoimport版本4.0及早期版本
  • 各种MongoDB工具的--query选项
  • mongo shell

严格模式输出

在4.2版本之前, Mongoexport 以MongoDB扩展JSON v1的严格模式输出数据。

在mongo shell模式下输出

在4.2版本之前, Bsondump 以mongo shell模式输出。

BSON数据类型及其相关表示方式

以下介绍了BSON数据类型以及严格模式和mongo Shell模式下的相关表示方式。

Binary

data_binary

严格模式 mongo Shell模式
{ 
  	"$binary": "<bindata>", 
    "$type": "<t>" 
}           
BinData ( <t>, <bindata> )           

其中值的含义如下:

  • <bindata>是二进制字符串的base64表示。
  • <t>是一个单字节指示数据类型的表示方式。在严格模式下,它是一个十六进制字符串,在Shell模式下,它是一个整数。请参见扩展BSON文档http://bsonspec.org/spec.html。

Date

data_date

严格模式 mongo Shell模式
{ "$date": "<date>" }           
new Date ( <date> )           

在严格模式下,<date> 是一个 ISO-8601 的日期格式,后面必须跟随一个强制的时区字段,格式为 YYYY-MM-DDTHH:mm:ss.mmm<+/-Offset>。

在 Shell 模式下,<date> 是一个64位有符号整数的 JSON 表示形式,表示自 UTC 纪元以来的毫秒数。

Timestamp

data_timestamp

严格模式 mongo Shell模式
{ "$timestamp": { "t": <t>, "i": <i> } }           
Timestamp( <t>, <i> )           

其中值的含义如下:

  • <t> 是自纪元以来经过的秒数的 32 位无符号整数的 JSON 表示形式。
  • <i> 是一个 32 位无符号整数,表示递增值。

Regular Expression

data_regex

严格模式 mongo Shell模式
{ 
  "$regex": "<sRegex>",
  "$options": "<sOptions>" 
}           
/<jRegex>/<jOptions>           

以下是这些值的定义:

  • <sRegex> 是一个包含有效 JSON 字符的字符串。
  • <jRegex> 是一个字符串,可以包含有效的 JSON 字符和未转义的双引号 (") 字符,但不能包含未转义的正斜杠 (/) 字符。
  • <sOptions> 是一个字符串,包含由字母表示的正则表达式选项。
  • <jOptions> 是一个字符串,只能包含字符 'g'、'i'、'm' 和 's'(在 v1.9 中添加)。因为 JavaScript 和 mongo Shell 表示仅支持有限范围的选项,所以在转换为此表示形式时,任何不符合规范的选项都将被丢弃。

OID

data_oid

严格模式 mongo Shell模式
{ "$oid": "<id>" }           
ObjectId( "<id>" )           

以下是这些值的定义:

  • <id> 是一个由 24 个十六进制字符组成的字符串。

DB Reference

data_ref

严格模式 mongo Shell模式
{ "$ref": "<name>", "$id": "<id>" }           
DBRef("<name>", "<id>")           

以下是这些值的定义:

  • <name> 是一个包含有效 JSON 字符的字符串。
  • <id> 是任何有效的扩展 JSON 类型。

Undefined Type

data_undefined

严格模式 mongo Shell模式
{ "$undefined": true }           
undefined           

JavaScript/BSON undefined 类型的表示形式。

您不能在查询文档中使用 undefined。考虑下面插入到 people 集合中的文档:

db.people.insert( { name : "Sally", age : undefined } )           

以下查询会返回错误:

db.people.find( { age : undefined } )
db.people.find( { age : { $gte : undefined } } )           

但是,您可以使用 $type 查询 undefined 值,如下所示:

db.people.find( { age : { $type : 6 } } )           

该查询将返回所有 age 字段的值为 undefined 的文档。

MinKey

data_minkey

严格模式 mongo Shell模式
{ "$minKey": 1 }           
MinKey           

MinKey BSON 数据类型的表示形式,它比所有其他类型都要低。有关 BSON 类型比较顺序的更多信息,请参见比较/排序顺序。

MaxKey

data_maxkey

严格模式 mongo Shell模式
{ "$maxKey": 1 }           
MaxKey           

MaxKey BSON 数据类型的表示形式,它比所有其他类型都要高。有关 BSON 类型比较顺序的更多信息,请参见比较/排序顺序。

NumberLong

data_numberlong

严格模式 mongo Shell模式
{ "$numberLong": "<number>" }           
NumberLong( "<number>" )           

NumberLong 是一个 64 位有符号整数。您必须包含引号,否则它将被解释为浮点数,导致精度损失。

例如,以下命令使用和不使用引号将 9223372036854775807 插入为 NumberLong:

db.json.insert( { longQuoted : NumberLong("9223372036854775807") } )
db.json.insert( { longUnQuoted : NumberLong(9223372036854775807) } )           

当您检索文档时,longUnQuoted 的值已更改,而 longQuoted 保留了其准确性:

db.json.find()
{ "_id" : ObjectId("54ee1f2d33335326d70987df"), "longQuoted" : NumberLong("9223372036854775807") }
{ "_id" : ObjectId("54ee1f7433335326d70987e0"), "longUnQuoted" : NumberLong("-9223372036854775808") }           

NumberDecimal

自版本 3.4 新增。

data_numberdecimal

严格模式 mongo Shell模式
{ "$numberDecimal": "<number>" }           
NumberDecimal( "<number>" )           

NumberDecimal 是高精度小数。您必须包含引号,否则输入数字将被视为 double,导致数据丢失。

例如,以下命令使用和不使用引号将 123.40 插入为 NumberDecimal:

db.json.insert( { decimalQuoted : NumberDecimal("123.40") } )
db.json.insert( { decimalUnQuoted : NumberDecimal(123.40) } )           

当您检索文档时,decimalUnQuoted 的值已更改,而 decimalQuoted 保留了其指定的精度:

db.json.find()
{ "_id" : ObjectId("596f88b7b613bb04f80a1ea9"), "decimalQuoted" : NumberDecimal("123.40") }
{ "_id" : ObjectId("596f88c9b613bb04f80a1eaa"), "decimalUnQuoted" : NumberDecimal("123.400000000000") }