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 / 跨版本迁移 |
| 二进制 BSON | 2f 00 00 00 07 5f 69 64 … | mongodump / 网络协议 / .bson 文件 |
输入和输出任意搭配:粘 mongosh shell 输出 → 选 Canonical → 得到带类型保真的 EJSON;粘二进制 hex → 选 Pretty → 得到扁平易读 JSON。
输入框接受直接粘贴 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 会丢精度,本工具自动保留字符串形式 |
Decimal128 | 34 位有效十进制 | 永远以字符串存,避免二进制浮点 0.1+0.2≠0.3 问题 |
Date | ±253 ms(约 28 万年) | Pretty 模式输出 ISO,Canonical 模式包到 {"$numberLong"} |
.bson:mongodump 产物是多个 BSON 文档拼接,本工具只解第一条{key: 模式可能被误判为不带引号的 key——遇到时把字符串内的内容用 \\ 转义一下即可bsondump 命令行工具Pretty 是扁平 JSON:ObjectId 拍成 hex 字符串、Date 拍成 ISO 字符串,最易读但丢类型——不能再被 mongo/驱动直接吃进去。Relaxed EJSON 是 MongoDB 标准的"宽松扩展 JSON":日期写 {"$date":"2024-..."},安全整数走原生 number,可塞回驱动,最常用。Canonical EJSON 把所有数字也包到 {"$numberInt"|"$numberLong"|"$numberDouble"},类型完全保真,存档/迁移用。
直接粘,不用预处理。mongosh 输出里的 ObjectId("...")、ISODate("...")、NumberLong("...")、NumberDecimal("...")、BinData(t, "...")、UUID("...")、Timestamp(t,i)、MinKey、MaxKey,本工具都会自动转成 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 是 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 是 IEEE 754 十进制 128 位浮点,专门为金融、币种等需要精确十进制的场景设计——0.1 + 0.2 在 Decimal128 下严格等于 0.3,而 JS 原生 Number 是二进制浮点,这个加法会得到 0.30000000000000004。直接转 number 会丢精度。所以三种输出格式下,Decimal128 都保留字符串(Relaxed/Canonical 包成 {"$numberDecimal":"..."})。
不会。所有解析、转换、ObjectId 时间戳计算都在浏览器本地完成,不发起任何网络请求,可断网使用。bson 库直接打包到页面 JS,无外部依赖。
{"$date":"..."},安全整数走原生 number,可塞回驱动,最常用 Canonical官方 Canonical EJSON:所有数字都包到 {"$numberLong"|"$numberInt"|"$numberDouble"},类型完全保真,存档/迁移用 ObjectId("...") · ISODate("...") · NumberLong("...") · NumberInt(...) · NumberDecimal("...") · BinData(t, "b64") · UUID("...") · Timestamp(t,i) · MinKey / MaxKey{ name: "Alice" })也会自动加引号NumberLong / int64:超过 253 时输出 字符串,避免 JS Number 丢精度NumberDecimal / Decimal128:始终以字符串保留十进制精度