支持遍历的二进制JSON格式

Binary JSON format that supports traversal

有谁知道一种序列化格式:

  1. 是二进制的,至少比较紧凑,
  2. 可以存储JSON风格的数据(不是 Protobuf、Thrift等),
  3. 支持遍历(即你不需要解析整个文档来阅读它的一部分),并且
  4. 支持大文件(例如 30 GB)吗?

我看过以下内容:

BSON 非常接近,但最大文件大小让我无法接受。有什么格式可以用吗?显然我可以自己写,但是有太多的二进制 JSON 格式,肯定有人制作了一个像样的格式吧?

编辑: "traversal" 我的意思和 the BSON authors mean 一样 - 你应该能够找到给定的对象而不必解析整个文件。亚马逊称此为 "sparse" 或 "shallow" 阅读。

找到一个! Amazon Ion. From the FAQ:

Many reads are shallow or sparse, meaning that the application is focused on only a subset of the values in the stream, and that it can quickly determine if full materialization of a value is required.

In the spirit of these principles, the Ion specification includes features that make Ion’s binary encoding more efficient to read than other schema-free formats. These features include length-prefixing of binary values and Ion’s use of symbol tables.

关于 Ion 的简要说明:

  • 好像设计得比较好
  • 所有值都是 TLV 编码的,这使得它可以遍历(是的!)
  • 长度值不限于 32 位(是的!)
  • 它具有比 JSON 稍微丰富的对象模型,例如它支持时间戳、二进制数据、类型注释和 S 表达式(不确定为什么)。
  • 它支持一个符号table所以字段名可以被保留!这意味着它可能 显着 比所有其他二进制 JSON 格式更紧凑。

不是很流行。库仅适用于几种语言,我什至找不到使用它的命令行工具。尽管如此,如果您想要这些功能,它似乎是唯一的选择!

编辑:

最后我们选择了非常优秀的 SQLite。它并没有真正遵循 JSON 数据模型,但它确实让您可以非常轻松地进行稀疏读取,而且速度非常快。另一种可能性是 DuckDB,它是 SQLite 的一种现代版本,但支持较少。

对于CBOR,我和你有类似的要求;对我来说不受 30GB 的限制是通过无限惰性列表解决的,并且没有单个对象大于 16MB(我只需要 TB 的“中等”大小的块 - 当然你的要求可能不同)。

然而,使用 'traversable' 这很容易,有一个定义嵌套 CBOR 的 TAG。解码时,您将标签视为不存在。这样你就可以拥有

{ "key1" : [cbor-tag] <<binary-cbor-subtree>>,
  "key2" : [cbor-tag] <<binary-cbor-subtree>>
}

以这种方式,您将“跳过”“值”作为单个解码+搜索,但如果您只是执行 cbor-to-json,解析器将不得不解码标记的二进制作为 CBOR .. 因此你可以两全其美(BSON v.s.CBOR)既可流式传输(通过不定映射 len)又可遍历。

当然这需要专门的编码器,但至少解码器应该是trivial/standard。

对于我们来说,我们碰巧使用了可以识别标记二进制值的专用 encoders/decoders(因为我们需要维护一个包含潜在巨大值的多 GB 映射)。