MongoDB 数据类型
目录
BSON 类型
二进制数据(Binary Data)
ObjectId
ObjectId定义
文档中的ObjectId
ObjectId的单调性
字符串(String)
时间戳(Timestamps)
日期(Date)
BSON类型的排序
数值类型的比较
字符串比较
数组的比较
对象的比较
日期和时间戳
不存在字段
二进制数据
Mongodb是文档型数据库,文档表示一条数据记录。文档由键值对构成。
//一个文档示例
{"key_1": value_1,"key_2": value_2...
}
其中,键值对中的键,或叫做字段名称,是由字符类型来定义的。而值的类型,是BSON类型中的某一个类型。
BSON 类型
BSON是一个二进制序列格式,用来保存文档,实现在mongodb中的远程调用。Mongodb支持不同的BSON类型,现在可用的BSON类型,其数字代码,字符识别码列在下表中。
| 类型 | 数字代码 | 别名 | 中文名 |
| Double | 1 | "double" | 浮点型 |
| String | 2 | "string" | 字符串 |
| Object | 3 | "object" | 对象 |
| Array | 4 | "array" | 数组 |
| Binary data | 5 | "binData" | 二进制数据 |
| ObjectId | 7 | "objectId" | 对象id |
| Boolean | 8 | "bool" | 布尔 |
| Date | 9 | "date" | 日期 |
| Null | 10 | "null" | 空值 |
| Regular Expression | 11 | "regex" | 正则表达式 |
| JavaScript | 13 | "javascript" | javascript脚本 |
| 32-bit Integer | 16 | "int" | 整型 |
| Timestamp | 17 | "timestamp" | 时间戳 |
| 64-bit Integer | 18 | "long" | 长整型 |
| Decimal128 | 19 | "decimal" | 小数 |
| Min Key | -1 | "minKey" | 最小值 |
| Max Key | 127 | "maxKey" | 最大值 |
在Mongodb中,可以使用数字代码和别名作为过滤条件查询文档。在聚合操作中,可以获取字段类型的别名。或者根据返回的字段类型实现不同的逻辑。
如查询字段类型是数组类型的数据
//使用字符串"array"和数字类型4查询字段类型是数组的数据
db.collection.find({<field_name>: {$type: "array"}})
db.collection.find({<field_name>: {$type: 4}})
二进制数据(Binary Data)
BSON的二进制数据由字节数组组成。每一个二进制数据也有一个标志解析二进制数据的子类型。下面表描述了子类型。
| 数字 | 子类型 |
| 0 | 通用二进制数据 |
| 1 | Function data |
| 2 | Binary(old) |
| 3 | UUID(old) |
| 4 | UUID |
| 5 | MD5加密 |
| 6 | 加密BSON数值 |
| 7 | 压缩时序数据 |
| 128 | 用户自定义 |
ObjectId
使用mongodb时 , 当集合中的文档没有_id字段时,会为文档自动生成一个ObjectId类型的_id。日常查询过程中,也能看到_id是ObjectId里带有一段字符串, 这个字符串代表什么意义,和其他类型的ID有什么相同或不同。本文研究mongodb官方文档,并通过实践来解释ObjectID这个数据类型。
ObjectId定义
ObjectId是一种小型的,几乎是唯一的,易于产生和排序的数据结构。长度是12个字节,由3部分组成
- 4个字节的时间戳,表明objectId的创建时间,以秒为单位的unix时间
- 5个字节的随机字符串,在运行机器上的进程中是唯一的
- 3个字节的增长计数器,初始值是一个随机数
其中时间戳和增长计数器与其他BSON类型不同,是按照高位优先排序。
如果使用数字类型来创建ObjectID, ObjectID中的时间戳,会被数字值来替代。
//使用数字类型定义3个ObjectID
db.inventory.insertMany([{part: 'AB307',_id: ObjectId(1)
},{part: 'AB307',_id: ObjectId(2)
},{part: 'AB307',_id: ObjectId(3)
}])// 产生的id中,数字类型替代了4个字节的时间戳
{"acknowledged" : true,"insertedId" : ObjectId("000000013e53cb5bc48f4e54")
}
{"acknowledged" : true,"insertedId" : ObjectId("000000023e53cb5bc48f4e55")
}
{"acknowledged" : true,"insertedId" : ObjectId("000000033e53cb5bc48f4e56")
}
上面代码的运行结果中可以看到,4个字节长度的00000001,00000002,00000003,替代了时间错。而后面3个字节长度的增长计数器,8f4e54,8f4e55,8f4e56在每一条新纪录插入时,都会增长。而中间3e53cb5bc4这个长度为5个字节的字符串,是由运行机器进程中随机产生的字符串。
时间戳+随机字符串+自增长字符串,保证了objectId的唯一性。
文档中的ObjectId
Mongodb的每一个文档都需要有唯一的_id字段作为主键。如果没有_id字段,mongodb自动添加一个ObjectId作为_id字段。这对于设置{upsert:true}的更新语句插入数据同样适用。
使用ObjectId作为_id字段的好处
- 在mongosh中,通过ObjectId.getTimestamp()方法,获取文档创建时间
//运行代码
ObjectId("655ef22e69185fac9ce3ce92").getTimestamp()
//获取创建时间
ISODate("2023-11-23T14:33:18.000+08:00")
- 按照_id排序,等价于按照文档创建时间排序
ObjectId的单调性
ObjectId虽然按照时间来产生,并带有随机数保证其唯一性。但objectId并不是单调的,受到两个因素影响
- 产生objectId仅仅以秒为单位,记录下来unix时间。当同一秒钟产生多个objectId时,并不能保证每一个objectid的排列顺序。
- 通过client产生的ObjectId, 其时间错可能与服务器时间不一致
字符串(String)
BSON类型的字符串是UTF-8格式的。各种语言连接mongodb时,通常都会使用UTF-8格式的字符串。这种格式保证了大部分语言的通用性。
时间戳(Timestamps)
BSON 的timestamps类型是一种内部使用的特殊格式。这种类型与常见的日期(Date)类型不同。timestamps类型是一个64位的数值
-
- 前面32位的unix时间,精确到秒
- 后32位的自增型操作数。表示在一秒内的操作数。
虽然BSON格式是小端序的,因此首先存储最低有效位,但在所有平台上,mongod实例总是在序数值之前比较time_t值,而不考虑端序。
在同一个mongodb运行实例中,timestamp值是唯一的。
在复制集中,oplog有一个时间类型的ts字段。这个字段使用timestamp类型表示操作时间。
当在文档中插入一个空的timestamp数值时,mongodb会将空的timestamp数字换成当前时间。但如果_id字段包含一个空的timestamp值时,mongodb不会替换空的timestamp.
db.test.insert({ts: new Timestamp(), _id: {ts: new Timestamp()}})
{"acknowledged" : true,"insertedId" : {"ts" : Timestamp(0, 0)}
}db.test.find()
{"_id" : {"ts" : Timestamp(0, 0) //_id字段中的时间戳未被替换},"ts" : Timestamp(1703731318, 1) //顶层字段的时间戳被替换成当前的操作时间
}
日期(Date)
日期类型是一个64位字符,表示了字1970年1月1日以来经过的毫秒数。日期时间是有符号的,负数表示1970年以前的时间。64位的字符,可以表示过去和现在共2.9亿年的时间。
var mydate1 = new Date()
var mydate2 = ISODate()
console.log(mydate1.toString())
console.log(mydate2.toString())
console.log(mydate1.getMonth())Thu Dec 28 2023 10:48:15 GMT+0800 (China Standard Time)
Thu Dec 28 2023 10:48:15 GMT+0800 (China Standard Time)
11
BSON类型的排序
在mongodb对BSON类型进行排序时,按照下面的类型进行排序。从小到大的顺序依次为
| 序号 | 类型 |
| 1 | MinKey |
| 2 | Null |
| 3 | Numbers(ints,longs,doubles,decimals) |
| 4 | String |
| 5 | Object |
| 6 | Array |
| 7 | BinData |
| 8 | ObjectId |
| 9 | Boolean |
| 10 | Date |
| 11 | Timestamp |
| 12 | RegularExpression |
| 13 | MaxKey |
这个排序怎样理解,不妨使用下面的测试用例来解释。插入13条各种类型的数据。当使用正序排列,即从小到大排列时,顺序从MinKey到MaxKey. 当使用倒序排列时,顺序相反。
db.test.insertMany([{value: MinKey()},{value: null},{value: 1},{value: "1"},{value: {a: 1}},{value: [1]},{value: new BinData(5,"1")},{value: ObjectId(1)},{value: true},{value: new Date()},{value: new Timestamp()},{value: /a/},{value: MaxKey()},])//正序排列
db.test.find().sort('value')
/* 1 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557ef"),"value" : MinKey()
},/* 2 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f0"),"value" : null
},/* 3 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f1"),"value" : 1
},/* 4 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f4"),"value" : [ 1 ]
},/* 5 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f2"),"value" : "1"
},/* 6 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f3"),"value" : {"a" : 1}
},/* 7 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f5"),"value" : MD5("")
},/* 8 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f6"),"value" : ObjectId("000000019ef5a82e298557ee")
},/* 9 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f7"),"value" : true
},/* 10 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f8"),"value" : ISODate("2023-12-28T11:04:43.958+08:00")
},/* 11 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f9"),"value" : Timestamp(1703732683, 1)
},/* 12 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557fa"),"value" : /a/
},/* 13 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557fb"),"value" : MaxKey()
}
//倒序排列
/* 1 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557fb"),"value" : MaxKey()
},/* 2 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557fa"),"value" : /a/
},/* 3 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f9"),"value" : Timestamp(1703732683, 1)
},/* 4 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f8"),"value" : ISODate("2023-12-28T11:04:43.958+08:00")
},/* 5 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f7"),"value" : true
},/* 6 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f6"),"value" : ObjectId("000000019ef5a82e298557ee")
},/* 7 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f5"),"value" : MD5("")
},/* 8 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f3"),"value" : {"a" : 1}
},/* 9 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f2"),"value" : "1"
},/* 10 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f1"),"value" : 1
},/* 11 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f4"),"value" : [ 1 ]
},/* 12 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557f0"),"value" : null
},/* 13 createdAt:12/28/2023, 11:04:43 AM*/
{"_id" : ObjectId("658ce5cb9ef5a82e298557ef"),"value" : MinKey()
}
数值类型的比较
mongodb比较数字类型时,int,long,double,decimal按照同一个类型进行比较。按照值大小进行排序。
字符串比较
默认字符串按照简单字节方法比较。即从第一个字符开始进行比较。当用户指定字符序时,mongodb比较字符串时,采用用户指定的字符序。
数组的比较
- 升序排列时,获取数组中最小的元素进行比较
- 降序排列时,比较数组中最大的元素
- 比较单元素数组与非数组数据时,mongodb会直接比较该数组中的元素和非数组元素值的大小。
- 空数组排列优先级别小于null或没有该字段的文档数据。
对象的比较
- 递归比较对象中的每一个键值对
- 字段类型相同时,比较字段名
- 字段名相同时,比较字段值
- 当前字段名,字段值都相同时,按照同样的方式比较下一个字段。字段较少的对象排列优先级小于字段多的对象。
日期和时间戳
日期排在时间错前
不存在字段
mongodb将不存在的字段看做空对象。即文档{ }与{a:null}的排列顺序相同
二进制数据
- 首先比较数据长度
- 数据长度相同时,比较子类型
- 数据长度和子类型相同时,按字节比较。
相关文章:
MongoDB 数据类型
目录 BSON 类型 二进制数据(Binary Data) ObjectId ObjectId定义 文档中的ObjectId ObjectId的单调性 字符串(String) 时间戳(Timestamps) 日期(Date) BSON类型的排序 数…...
Java 将 List 转换为 String常见方式
将 List 转换为 String的几种方式 使用 List的toString()方法将 List 转换为 String;结果前后会带有英文的中括号[],如:[1, 2, 3, 4, 5]使用Java8 stream流中的Collections.joining()方法,带有逗号分隔符或自定义分隔符将集合转成…...
Redis(认识NoSQL,认识redis,安装redis,redis桌面客户端,redis常见命令,redis的Java客户端)
文章目录 Redis快速入门1.初识Redis1.1.认识NoSQL1.1.1.结构化与非结构化1.1.2.关联和非关联1.1.3.查询方式1.1.4.事务1.1.5.总结 1.2.认识Redis1.3.安装Redis1.3.1.依赖库1.3.2.上传安装包并解压1.3.3.启动1.3.4.默认启动1.3.5.指定配置启动1.3.6.开机自启 1.4.Redis桌面客户端…...
idea 出现Cannot resolve symbol ‘springframework‘解决方法
Maven手动重新加载 1)File–>Invalidate Caches / Restart… 清理缓存,重启idea客户端 2)File–>Maven–>Reload project重新从maven中加载工程依赖的组件...
ubuntu22.04安装anacoda遇到的坑
这几天把用了3年的windows10换成了ubuntu22.04 各种环境都得配置,本文记录下遇到的坑。 1、anacoda在ubuntu上也可以用官方也提供了安装包,但是没有图形界面,需要以命令行的方式安装和运行配置 1.1 安装:官网下载后,…...
window的OPen方法,弹窗的特征
文章目录 一、介绍二、弹窗的特征 一、介绍 window.open() 方法是 JavaScript 中的一个内置方法,用于在浏览器中打开一个新的窗口或标签页。 语法: window.open(url, name, features, replace)二、弹窗的特征 open方法参数说明: 参数说明url要载入窗…...
DFS算法查找所有路径详解
DFS算法查找所有路径详解 算法介绍 深度优先搜索(Depth-First Search,DFS)是一种图遍历算法,它从起始节点开始,沿着一条路径尽可能深入,直到达到最深的节点,然后回溯到前一节点,继…...
单片机的存储、堆栈与程序执行方式
一、单片机存储区域 如图所示位STM32F103ZET6的参数: 单片机的ROM(内部FLASH):512KB,用来存放程序代码的空间。 单片机的RAM:64KB,一般都被分配为堆、栈、变量等的空间。 二、堆和栈的概念 …...
Web3开发成本和主要特性
多年来,技术不断进步,可帮助您的业务领先于竞争对手。如今,您可以看到许多更新和变化,使技术更加先进,对企业更加有用。到现在为止,web1.2和2.0比较流行,但是要知道web 3才是技术之父࿰…...
【数学建模美赛M奖速成系列】Matplotlib绘图技巧(一)
Matplotlib图像基础 写在前面1 基本绘图实例:sin、cos函数图2 plot()函数详解**kwargs参数: 3 matplotlib中绘图的默认配置4 设置图的横纵坐标的上下界5 设置横纵坐标上的记号6 调整图像的脊柱7 添加图例8 给一些特殊点加注释9 子图最后 写在前面 前面我…...
005、数据类型
1. 关于数据类型 Rust中,每个值都有其特定的数据类型,Rust会根据数据的类型来决定如何处理它们。 Rust是一门静态类型语言,它在编译程序的过程中就需要知道所有变量的具体类型。在大部分情况下,编译器可以根据我们如何绑定、使用变…...
软考网络工程师考试大纲(2018年最新版)
本书是全国计算机专业技术资格考试办公室组织编写的网络工程师考试大纲,本书除大纲内容外,还包括了人力资源和社会保障部、工业和信息化部的有关文件以及考试简介。 网络工程师考试大纲是针对本考试的计算机网络中级资格制定的。通过本考试的考生,可被用人单位择优聘任为工…...
【数据结构】栈【详解】
目录 栈的定义: 栈的声明与定义: 头文件的包含: 对栈的基本操作: 栈的初始化: 摧毁栈: 入栈: 编辑 出栈: 编辑 输出栈顶位置: 输出栈的当前大小: 判空操…...
CSS 纵向底部往上动画
<template><div class"container" mouseenter"startAnimation" mouseleave"stopAnimation"><!-- 旋方块 --><div class"box" :class"{ scale-up-ver-bottom: isAnimating }"><!-- 元素内容 --&g…...
常用的 MySQL 可视化客户端
数据库可视化客户端(GUI)让用户在和数据库进行交互时,能直观地查看、创建和修改对象,如:表、行和列。让数据库操作变得更方便了。 今天,我们来了解下目前市场上最常用的 MySQL 可视化客户端。 官方&#x…...
C#使用SyntaxTree获取.cs文件中的属性名和注释
有时候,我们可能需要获取.cs文件中的属性和对应的注释来生成一些代码,比如SQL查询什么的。 但使用正则匹配有时候会不准确。搜索了下,发现微软提供了代码解析的API。 具体如下两个方法: /// <summary> /// 获取所有属性和…...
基于价值认同的需求侧电能共享分布式交易策略(matlab完全复现)
目录 1 主要内容 2 部分程序 3 程序结果 4 下载链接 1 主要内容 该程序完全复现《基于价值认同的需求侧电能共享分布式交易策略》,针对电能共享市场的交易机制进行研究,提出了基于价值认同的需求侧电能共享分布式交易策略,旨在降低电力市…...
门控循环单元(GRU)-多输入回归预测
目录 一、程序及算法内容介绍: 基本内容: 亮点与优势: 二、实际运行效果: 三、部分程序: 四、全部代码数据分享: 一、程序及算法内容介绍: 基本内容: 本代码基于Matlab平台编译…...
电池管理系统BMS中SOC算法通俗解析(二)
下面简单介绍下我们BMS保护板使用的SOC估算方法。我们算法的主要是针对电流积分法计算SOC的局限性进行改进: ●电池包第一次上电使用开路电压法估算SOC。第一次上电,根据电池包厂家给出的电压和剩余容量二维关系图大概估算出目前电池包的剩余容量即SOC。…...
YOLOv5改进 | 2023主干篇 | 华为最新VanillaNet主干替换Backbone实现大幅度长点
一、本文介绍 本文给大家来的改进机制是华为最新VanillaNet网络,其是今年最新推出的主干网络,VanillaNet是一种注重极简主义和效率的神经网络架构。它的设计简单,层数较少,避免了像深度架构和自注意力这样的复杂操作(需要注意的是…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
【若依】框架项目部署笔记
参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作: 压缩包下载:http://download.redis.io/releases 1. 上传压缩包,并进入压缩包所在目录,解压到目标…...
