东莞市官网网站建设公司,餐饮网站建设研究问题,百度站长管理平台,网页搜索怎么设置BSON 协议与数据类型
MongoDB 为什么会使用 BSON#xff1f;
JSON 是当今非常通用的一种跨语言 Web 数据交互格式#xff0c;属 ECMAScript 标准规范的一个子集。JSON #xff08;JavaScript Object Notation#xff0c;JS 对象简谱#xff09;即 JavaScript 对象表示法…BSON 协议与数据类型
MongoDB 为什么会使用 BSON
JSON 是当今非常通用的一种跨语言 Web 数据交互格式属 ECMAScript 标准规范的一个子集。JSON JavaScript Object NotationJS 对象简谱即 JavaScript 对象表示法它是 JavaScript 对象的一种文本表现形式。作为一种轻量级的数据交换格式JSON 的可读性非常好而且非常便于系统生成和解析这些优势也让它逐渐取代了 XML 标准在 Web 领域的地位当今许多流行的 Web 应用开发框架如 SpringBoot 都选择了 JSON 作为默认的数据编/解码格式。JSON 只定义了 6 种数据类型
string: 字符串number : 数值object: JS 的对象形式用 {key:value} 表示可嵌套array: 数组JS 的表示方式 [value]可嵌套true/false: 布尔类型null: 空值
大多数情况下使用 JSON 作为数据交互格式已经是理想的选择但是 JSON 基于文本的解析效率并不是最好的在某些场景下往往会考虑选择更合适的编/解码格式一些做法如
在微服务架构中使用 gRPC基于 Google 的 Protobuf可以获得更好的网络利用率。分布式中间件、数据库使用私有定制的 TCP 数据包格式来提供高性能、低延时的计算能力。
BSON 由 10gen 团队设计并开源目前主要用于 MongoDB 数据库。BSONBinary JSON是二进制版本的 JSON其在性能方面有更优的表现。BSON 在许多方面和 JSON 保持一致其同样也支持内嵌的文档对象和数组结构。二者最大的区别在于 JSON 是基于文本的而 BSON 则是二进制字节流编/解码的形式。在空间的使用上BSON 相比 JSON 并没有明显的优势。MongoDB 在文档存储、命令协议上都采用了 BSON 作为编/解码格式主要具有如下优势
类 JSON 的轻量级语义支持简单清晰的嵌套、数组层次结构可以实现模式灵活的文档结构。更高效的遍历BSON 在编码时会记录每个元素的长度可以直接通过 seek 操作进行元素的内容读取相对 JSON 解析来说遍历速度更快。更丰富的数据类型除了 JSON 的基本数据类型BSON 还提供了 MongoDB 所需的一些扩展类型比如日期、二进制数据等这更加方便数据的表示和操作。
BSON 的数据类型
MongoDB 中一个 BSON 文档最大大小为 16M文档嵌套的级别不超过100。 https://www.mongodb.com/docs/v6.0/reference/bson-types/ TypeNumberAliasNotesDouble1“double”String2“string”Object3“object”Array4“array”Binary data5“binData”二进制数据Undefined6“undefined”Deprecated.ObjectId7“objectId”对象ID用于创建文档IDBoolean8“bool”Date9“date”Null10“null”Regular Expression11“regex”正则表达式DBPointer12“dbPointer”Deprecated.JavaScript13“javascript”Symbol14“symbol”Deprecated.JavaScript code with scope15“javascriptWithScope”Deprecated in MongoDB 4.4.32-bit integer16“int”Timestamp17“timestamp”64-bit integer18“long”Decimal12819“decimal”New in version 3.4.Min key-1“minKey”表示一个最小值Max key127“maxKey”表示一个最大值 t y p e 操作符 b r / type 操作符br / type操作符br/type 操作符基于 BSON 类型来检索集合中匹配的数据类型并返回结果。
db.books.find({title : {$type : 2}})
// 或者
db.books.find({title : {$type : string}})日期类型
MongoDB 的日期类型使用 UTCCoordinated Universal Time即世界协调时进行存储也就是 0 时区的时间。
db.dates.insertMany([{data1:Date()},{data2:new Date()},{data3:ISODate()}])
db.dates.find().pretty()使用 new Date 与 ISODate 最终都会生成 ISODate 类型的字段对应于 UTC 时间。
ObjectId 生成器
MongoDB 集合中所有的文档都有一个唯一的 _id 字段作为集合的主键。在默认情况下_id 字段使用 ObjectId 类型采用 16 进制编码形式共 12 个字节。为了避免文档的 _id 字段出现重复ObjectId 被定义为 3 个部分
4 字节表示 Unix 时间戳秒。5 字节表示随机数机器号进程号唯一。3 字节表示计数器初始化时随机。
大多数客户端驱动都会自行生成这个字段比如 MongoDB Java Driver 会根据插入的文档是否包含 _id 字段来自动补充 ObjectId 对象。这样做不但提高了离散性还可以降低 MongoDB 服务器端的计算压力。在 ObjectId 的组成中5 字节的随机数并没有明确定义客户端可以采用机器号、进程号来实现
属性/方法描述str返回对象的十六进制字符串表示。ObjectId.getTimestamp()将对象的时间戳部分作为日期返回。ObjectId.toString()以字符串文字“”的形式返回 JavaScript 表示ObjectId(…)。ObjectId.valueOf()将对象的表示形式返回为十六进制字符串。返回的字符串是 str 属性。
生成一个新的 ObjectId
x ObjectId()内嵌文档和数组
内嵌文档
一个文档中可以包含作者的信息包括作者名称、性别、家乡所在地一个显著的优点是当我们查询 book 文档的信息时作者的信息也会一并返回。
db.books.insert({title: 撒哈拉的故事,author: {name:三毛,gender:女,hometown:重庆}
})查询三毛的作品
db.books.find({author.name:三毛})修改三毛的家乡所在地
db.books.updateOne({author.name:三毛},{$set:{author.hometown:重庆/台湾}})数组
除了作者信息文档中还包含了若干个标签这些标签可以用来表示文档所包含的一些特征如豆瓣读书中的标签tag。增加 tags 标签
db.books.updateOne({author.name:三毛},{$set:{tags:[旅行,随笔,散文,爱情,文学]}})查询数组元素
# 会查询到所有的tags
db.books.find({author.name:三毛},{title:1,tags:1})
# 利用$slice获取最后一个tag
db.books.find({author.name:三毛},{title:1,tags:{$slice:-1}})$silice 是一个查询操作符用于指定数组的切片方式 数组末尾追加元素可以使用 $push 操作符
db.books.updateOne({author.name:三毛},{$push:{tags:猎奇}})$push 操作符可以配合其他操作符一起实现不同的数组修改操作比如和 $each 操作符配合可以用于添加多个元素
db.books.updateOne({author.name:三毛},{$push:{tags:{$each:[伤感,想象力]}}})如果加上 $slice 操作符那么只会保留经过切片后的元素
db.books.updateOne({author.name:三毛},{$push:{tags:{$each:[伤感,想象力],$slice:-3}}})根据元素查询
# 会查出所有包含伤感的文档
db.books.find({tags:伤感})
# 会查出所有同时包含伤感,想象力的文档
db.books.find({tags:{$all:[伤感,想象力]}})嵌套型的数组
数组元素可以是基本类型也可以是内嵌的文档结构
{tags:[{tagKey:xxx,tagValue:xxxx},{tagKey:xxx,tagValue:xxxx}]
}这种结构非常灵活一个很适合的场景就是商品的多属性表示。
一个商品可以同时包含多个维度的属性比如尺码、颜色、风格等使用文档可以表示为
db.goods.insertMany([{name:羽绒服,tags:[{tagKey:size,tagValue:[M,L,XL,XXL,XXXL]},{tagKey:color,tagValue:[黑色,宝蓝]},{tagKey:style,tagValue:韩风}]
},{name:羊毛衫,tags:[{tagKey:size,tagValue:[L,XL,XXL]},{tagKey:color,tagValue:[蓝色,杏色]},{tagKey:style,tagValue:韩风}]
}])以上的设计是一种常见的多值属性的做法当我们需要根据属性进行检索时需要用到 $elementMatch 操作符
# 筛选出color黑色的商品信息
db.goods.find({tags:{$elemMatch:{tagKey:color,tagValue:黑色}}
})如果进行组合式的条件检索则可以使用多个 $elemMatch 操作符
# 筛选出color蓝色并且sizeXL的商品信息
db.goods.find({tags:{$all:[{$elemMatch:{tagKey:color,tagValue:黑色}},{$elemMatch:{tagKey:size,tagValue:XL}}] }
})固定封顶集合 https://www.mongodb.com/docs/manual/core/capped-collections/ 固定集合capped collection是一种限定大小的集合其中 capped 是覆盖、限额的意思。跟普通的集合相比数据在写入这种集合时遵循 FIFO 原则。可以将这种集合想象为一个环状的队列新文档在写入时会被插入队列的末尾如果队列已满那么之前的文档就会被新写入的文档所覆盖。通过固定集合的大小我们可以保证数据库只会存储“限额”的数据超过该限额的旧数据都会被丢弃。
使用示例
创建固定集合
db.createCollection(logs,{capped:true,size:4096,max:10})max指集合的文档数量最大值这里是 10 条 size指集合的空间占用最大值这里是 4096 字节4 KB 这两个参数会同时对集合的上限产生影响。也就是说只要任一条件达到阈值都会认为集合已经写满。其中 size 是必选的而 max 则是可选的。可以使用collection.stats命令查看文档的占用空间
db.logs.stats()将普通集合转换为固定集合
db.runCommand({convertToCapped: mycoll, size: 100000})测试尝试在这个集合中插入 15 条数据再查询会发现由于文档数量上限被设定为 10 条前面插入的 5 条数据已经被覆盖了。
for(var i0;i15;i){db.logs.insert({t:row-i})
} 适用场景
固定集合很适合用来存储一些“临时态”的数据。“临时态”意味着数据在一定程度上可以被丢弃。同时用户还应该更关注最新的数据随着时间的推移数据的重要性逐渐降低直至被淘汰处理。一些适用的场景如下
系统日志
这非常符合固定集合的特征而日志系统通常也只需要一个固定的空间来存放日志。在 MongoDB 内部副本集的同步日志oplog就使用了固定集合。
存储少量文档
如最新发布的 TopN 条文章信息。得益于内部缓存的作用对于这种少量文档的查询是非常高效的。