JSON对象的增量编码[关闭]

Posted

技术标签:

【中文标题】JSON对象的增量编码[关闭]【英文标题】:Delta encoding for JSON objects [closed] 【发布时间】:2011-11-11 16:42:01 【问题描述】:

是否有标准库或工具用于计算和应用 JSON 文档的差异?基本上我有一堆大型文档,我想在网络上保持同步,并且我希望避免每次我想要同步它们时都重新发送它们的整个状态(因为其中许多变量不会改变)。换句话说,我只想传输改变的字段,而不是重新传输整个对象。我认为拥有以下一组方法会很方便:

//Start with two distinct objects on the server
// prev represents a copy of the state of the object on the client
// next represents a copy of the state of the object on the server
//
//1. Compute a patch
patch = computePatch(prev, next);

//2. Send patch over the network

//3. Apply the patch on the client
applyPatch(prev, patch);

//Final invariant:
//   prev represents an equivalent object to JSON.parse(JSON.stringify(next))

我当然可以自己实现一个,但有很多边缘情况需要考虑。以下是我能想到的一些简单(虽然有些不满意)的方法,例如:

    滚动我自己的 JSON 修补程序。渐近地,这可能是最好的方法,因为它可以支持 JSON 文档的所有相关特性,同时支持一些专门的方法来做一些事情,比如区分整数、双精度和字符串(使用相对编码/编辑距离) .但是,JSON 有很多特殊情况,我对在没有大量测试的情况下尝试这样做有点怀疑,所以我更愿意找到已经为我解决这个问题的东西,以便我可以信任它,并且不必担心由于我的 JSON 补丁错误而出现网络 Heisenbugs

    只需使用动态编程直接计算 JSON 字符串之间的编辑距离。不幸的是,如果客户端和服务器具有不同的 JSON 实现(即它们的字段的顺序可以不同地序列化),这将不起作用,并且作为二次时间操作也非常昂贵。

    使用协议缓冲区。协议缓冲区有一个内置的 diff 方法,它完全符合我的要求,它们是一种很好的二进制可序列化网络友好格式。不幸的是,因为它们也是严格类型的,所以它们缺乏使用 JSON 的许多优点,例如动态添加和删除字段的能力。目前这是我目前倾向于使用的方法,但它可能会使未来的维护变得非常糟糕,因为我需要不断更新我的每个对象。

    做一些非常讨厌的事情,比如为每种类型的对象创建一个自定义协议,并希望我在这两个地方都能做到(是的!)。

当然,我真正希望的是,*** 上的某个人能够通过引用节省空间的 javascript 对象differ/patcher 来拯救这一天,该对象已在生产环境和多个浏览器中经过良好测试。

*更新*

我开始编写自己的补丁程序,它的早期版本可以在 github 上找到:

https://github.com/mikolalysenko/patcher.js

我想因为这里似乎没有太多内容,所以我会接受 JSON 修补程序的有趣测试用例列表作为替代答案。

【问题讨论】:

既然您提到了“需要考虑的相当多的边缘情况”,如果您列举需要处理哪些边缘情况以及如何处理可能会有所帮助(对您的答案和后代而言)他们应该得到解决。 旁白:你问题的后半部分很好地表明你已经考虑过这个问题,并且作为“解决方法”答案的一部分可能很好,但与问题无关,对吧? 总是添加一个dirty 标志。 dirty 标志?我没看到。 “大”的定义很重要,以及它们如何变化很重要。除非你有大量的文档,并且一直有大量的微小变化,否则这可能是过早的优化。 【参考方案1】:

我在搜索 json-patch 的实现时遇到了这个问题。如果您自己滚动,您可能希望以此草稿为基础。

https://datatracker.ietf.org/doc/html/draft-pbryan-json-patch-00

【讨论】:

已经有一些JSON Patch的库,比如github.com/dharmafly/jsonpatch.js【参考方案2】:

我一直在 github 维护一个 json 差异和补丁库(是的,无耻的插件):

https://github.com/benjamine/JsonDiffPatch

它使用 Neil Fraser 的 diff_match_patch 库自动处理长字符串。 它适用于浏览器和服务器(在两个 env 上运行的单元测试)。 (完整的功能列表在项目页面上)

您可能需要的唯一未实现的是为特定对象注入自定义差异/补丁函数的选项,但这听起来并不难添加,欢迎您分叉它,甚至更好地发送拉取请求。

问候,

【讨论】:

【参考方案3】:

JSON 补丁标准已更新。

https://datatracker.ietf.org/doc/html/draft-ietf-appsawg-json-patch-10

您可以在https://github.com/Starcounter-Jack/Fast-JSON-Patch找到应用补丁和生成补丁的实现

【讨论】:

【参考方案4】:

使用JSON Patch,即the standard way to do this。

JSON Patch 是一种用于描述更改的格式 JSON 文档。它可用于避免在以下情况下发送整个文档 只有一部分发生了变化。与 HTTP PATCH 结合使用时 方法它允许对标准中的 HTTP API 进行部分更新 合规方式。

补丁文档本身就是 JSON 文档。

JSON 补丁在 IETF 的 RFC 6902 中指定。

大多数平台和编程语言都有库。

在撰写本文时,支持 Javascript、Python、php、Ruby、Perl、C、Java、C#、Go、Haskell 和 Erlang (full list and libraries here)。

这里是 javascript 列表

Fast-JSON-Patch 差异和补丁,在 NPM 上每周下载 509,361 次 jiff 差异和补丁,在 npm 上每周下载 5,075 次 jsonpatch-js 仅应用补丁,在 npm 中每周下载 2,014 次 jsonpatch.js 仅应用补丁,在 npm 中每周下载 1,470 次 JSON8 Patch 差异和补丁,在 npm 上每周下载 400 次

到目前为止,每个人(包括我自己)都在使用 Fast-JSON-Patch 库。它适用于 NodeJS 和浏览器。

【讨论】:

JSON-Patch 是第 1 步(计算补丁)的正确格式。如果您需要在第 2 步(通过网络发送补丁)最小化 JSON-Patch 大小,请使用 patchpack 库。 @Damir 由于还有许多其他紧凑且广泛使用的格式(FlatBuffers、protobuf、avro、bson、msgpack...),在 *** 中推广您自己的库时,请添加“我写了这个" 免责声明。

以上是关于JSON对象的增量编码[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

向 JSON 编码数组添加其他对象

将每个具有一个对象的 JSON 对象数组转换为 JSON 对象数组 [关闭]

使用常规编码器使对象 JSON 可序列化

kendoui parameterMap 解码 php 对象的正确 json 编码是啥?

Node.js 中 JSON 对象中的 JSON 对象 [关闭]

在 JSON 中编码嵌套的 python 对象