⭐ 觉得好用?收藏备用,下次直接打开
输入
输出格式
输出
🪪 ObjectId 时间戳
📊 BSON 类型统计

BSON / MongoDB 格式化 把 mongosh shell 输出、Extended JSON(EJSON)和二进制 BSON 三者互转,并自动从 ObjectId 提取生成时间。底层基于 MongoDB 官方的 bson JavaScript 库,所有处理都在浏览器本地完成,不会上传任何数据。

一表分清三种格式

格式长什么样用在哪
mongosh 输出{ _id: ObjectId("507f..."), ts: ISODate("2024...") }你在 mongo shell 里看到的样子,不是合法 JSON
Relaxed EJSON{"_id":{"$oid":"507f..."},"ts":{"$date":"2024..."}}驱动 JSON.stringify(doc) / 日志 / 接口默认输出
Canonical EJSON{"_id":{"$oid":"..."},"ts":{"$date":{"$numberLong":"1710..."}}}mongoexport --type=json --jsonFormat=canonical / 跨版本迁移
二进制 BSON2f 00 00 00 07 5f 69 64 …mongodump / 网络协议 / .bson 文件

输入和输出任意搭配:粘 mongosh shell 输出 → 选 Canonical → 得到带类型保真的 EJSON;粘二进制 hex → 选 Pretty → 得到扁平易读 JSON。

自动 mongosh 语法识别

输入框接受直接粘贴 mongo shell 的输出,下列形式会被自动改写成 EJSON 后再解析:

  • ObjectId("507f1f77bcf86cd799439011"){"$oid": "..."}
  • ISODate("2024-01-01T00:00:00Z") / new Date("..."){"$date": "..."}
  • NumberLong("9007199254740993"){"$numberLong": "..."}
  • NumberInt(30){"$numberInt": "30"}
  • NumberDecimal("128.50"){"$numberDecimal": "..."}
  • BinData(0, "base64"){"$binary": {"base64": "...", "subType": "00"}}
  • UUID("xxx-xxx-..."){"$binary": {..., "subType": "04"}}
  • Timestamp(1710498600, 1){"$timestamp": {"t": ..., "i": ...}}
  • MinKey / MaxKey{"$minKey": 1} / {"$maxKey": 1}

不带引号的 key({ name: "Alice" })和末尾逗号({ a: 1, })也会被自动修正。

精度处理(避免踩坑)

类型安全范围超出怎么办
int32 / Int32±2.1×109通常不会越界
Long / int64±9.2×1018超过 ±253(≈9×1015)后 JS Number 会丢精度,本工具自动保留字符串形式
Decimal12834 位有效十进制永远以字符串存,避免二进制浮点 0.1+0.2≠0.3 问题
Date±253 ms(约 28 万年)Pretty 模式输出 ISO,Canonical 模式包到 {"$numberLong"}

局限与注意

  • 不解 mongodump 的多文档 .bson:mongodump 产物是多个 BSON 文档拼接,本工具只解第一条
  • 不解 GridFS 分片:GridFS 文件需要先重组,本工具不处理
  • mongosh 字符串值里的特殊语法:极少数情况下,字符串值里出现的 {key: 模式可能被误判为不带引号的 key——遇到时把字符串内的内容用 \\ 转义一下即可
  • 大文档:单次解析 < 5MB 体验最佳;更大文件建议拆分或用 bsondump 命令行工具

📍使用场景

  • 看 mongosh 输出shell 里 `db.coll.findOne()` 出来的结果带 ObjectId/ISODate/NumberLong 一坨括号语法,贴进来一键格式化为可读 JSON 或标准 EJSON。
  • 在 BSON 二进制和 JSON 之间互看抓包/dump 文件拿到的二进制 BSON 字节,贴 hex 或拖入 .bson 文件即可看到结构;反过来也能把 EJSON 输出成 Pretty 格式贴回业务文档。
  • 调试 ObjectId 时间戳想知道某条记录是什么时候创建的,把 ObjectId 贴在含 `_id` 的文档里粘进来,下方面板自动列出每个 ObjectId 的生成时间(精确到秒)。
  • 在 Canonical / Relaxed EJSON 之间转老代码用 Canonical EJSON 存档(所有数字带类型包装),新接口要 Relaxed EJSON(int 走原生 number),切一下输出格式就直接转。

常见问题

Pretty / Relaxed / Canonical 三种输出有什么区别?

Pretty 是扁平 JSON:ObjectId 拍成 hex 字符串、Date 拍成 ISO 字符串,最易读但丢类型——不能再被 mongo/驱动直接吃进去。Relaxed EJSON 是 MongoDB 标准的"宽松扩展 JSON":日期写 {"$date":"2024-..."},安全整数走原生 number,可塞回驱动,最常用。Canonical EJSON 把所有数字也包到 {"$numberInt"|"$numberLong"|"$numberDouble"}类型完全保真,存档/迁移用。

能直接粘贴 mongosh 的输出吗?需要先转成 JSON?

直接粘,不用预处理。mongosh 输出里的 ObjectId("...")ISODate("...")NumberLong("...")NumberDecimal("...")BinData(t, "...")UUID("...")Timestamp(t,i)MinKeyMaxKey,本工具都会自动转成 EJSON 后再解析。不带引号的 key{ name: "Alice" })和末尾逗号也会自动处理。如果遇到字符串值里恰好包含 {key: 这种结构会有概率误判,这种情况建议手动加引号。

NumberLong 输出成字符串了,怎么办?

是有意为之。JavaScript 的 Number 只能精确表达 ±2<sup>53</sup>(≈9.007×10<sup>15</sup>)以内的整数,超过这个范围会丢精度——比如 9007199254740993 会被截成 9007199254740992。本工具检测到 Long 数值在安全整数范围内会输出原生 number;超过范围则保留字符串形式(Relaxed/Canonical EJSON 也维持 {"$numberLong":"..."} 包装)。需要做计算时用 BigInt 或 Decimal128。

ObjectId 的时间戳是怎么算出来的?

ObjectId 是 12 字节结构:前 4 字节 = Unix 秒级时间戳(big-endian)+ 5 字节随机机器/进程标识 + 3 字节单调递增计数器。本工具把前 4 字节按 big-endian 拆出 seconds,乘 1000 得到毫秒戳,再用 new Date() 转 ISO 字符串。这个时间戳就是 ObjectId 生成的瞬间——一般等同文档创建时间(除非业务代码自己塞了非默认 _id)。精度只到秒。

.bson 文件能直接打开吗?

能。把 .bson 文件拖进输入区或点 📎 选择,工具会读字节、自动切到 Hex 模式并立即解码。这适合看 mongodump 的产物或抓包里的 BSON payload。注意mongodump.bson 文件里其实是多个 BSON 文档拼接(每个文档自带长度),本工具当前只解析第一条;要批量看请用 bsondump 命令行工具。

Decimal128 为什么要存成字符串?直接存 number 不行吗?

不行Decimal128 是 IEEE 754 十进制 128 位浮点,专门为金融、币种等需要精确十进制的场景设计——0.1 + 0.2 在 Decimal128 下严格等于 0.3,而 JS 原生 Number 是二进制浮点,这个加法会得到 0.30000000000000004。直接转 number 会丢精度。所以三种输出格式下,Decimal128 都保留字符串(Relaxed/Canonical 包成 {"$numberDecimal":"..."})。

本工具会上传我的数据吗?

不会。所有解析、转换、ObjectId 时间戳计算都在浏览器本地完成,不发起任何网络请求,可断网使用。bson 库直接打包到页面 JS,无外部依赖。