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是一种注重极简主义和效率的神经网络架构。它的设计简单,层数较少,避免了像深度架构和自注意力这样的复杂操作(需要注意的是…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
