JSON对象的Delta编码

Mik*_*ola 37 javascript json node.js

是否有标准库或工具用于计算和应用差异到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))
Run Code Online (Sandbox Code Playgroud)

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

  1. 滚动我自己的JSON修补程序.渐近地,这可能是最好的方法,因为它可以支持JSON文档的所有相关功能,并支持一些专门的方法来执行诸如diffing int,double和string之类的东西(使用相对编码/编辑距离) .然而,JSON有很多特殊情况,我有点怀疑没有经过大量测试就试图这样做,所以我更愿意找到一些已经解决了这个问题的东西让我相信它,并且不必担心由于我的JSON补丁中的错误而出现的网络Heisenbugs

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

  3. 使用协议缓冲区.协议缓冲区有一个内置的diff方法,它正是我想要的,它们是一个很好的二进制可序列化的网络友好格式.不幸的是,因为它们也是严格类型的,它们缺少使用JSON的许多优点,例如动态添加和删除字段的能力.现在这是我目前倾向于的方法,但它可能使未来的维护非常可怕,因为我需要不断更新我的每个对象.

  4. 做一些非常讨厌的事情,比如为每种类型的对象制作一个自定义协议,并希望我能在两个地方做到正确(是的!).

当然,我真正希望的是这里有一个stackoverflow上的人通过参考一个节省空间的javascript对象不同/修补程序,在生产环境和多个浏览器中经过良好测试,以节省一天.

*更新*

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

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

我想因为这里似乎没有多少,我会接受一个JSON修补程序的有趣测试用例列表作为替代答案.

Ben*_*nja 12

我一直在github上维护一个json diff&patch库(是的,无耻的插件):

https://github.com/benjamine/JsonDiffPatch

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

你可能需要的唯一的东西,那就是没有实现的是为特定对象注入自定义diff/patch函数的选项,但这听起来不难添加,欢迎你使用它,甚至更好地发送pull请求.

问候,


iai*_*ain 5

我遇到了这个问题,寻找json-patch的实现.如果你自己动手,你可能希望以此草案为基础.

http://tools.ietf.org/html/draft-pbryan-json-patch-00


Jac*_*ter 5

JSON 补丁标准已更新。

http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-10

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