json - 修复无效的 JSON
问题描述
我正在处理一个非常大的 .json 文件,它是一长串花括号对,每个花括号对代表一本书中的一行。这是两个这样的对。他们只是一遍又一遍地继续:
{"index":{"_index":"tolstoy","_id":27}}
{"type":"line","line_id":100,"book":"War and Peace","speech_number":1,"speaker":"Sonya","text_entry":"Weep. It will do you good"}
{"index":{"_index":"tolstoy","_id":28}}
{"type":"line","line_id":101,"book":"War and Peace","speech_number":1,"speaker":"Sonya","text_entry":"I will call Pyotr."}
据我所知,第一个_id
是项目的 id。它从 0 到 200,000,对应于 JSON 文件中的总行数。反过来,line_id
是特定工作中的行。Speech number
是一个角色的演讲。
这是无效的 json(根据 JSON lint)。我有实际的文件,所以可以以任何我想要的方式修改它。
我想它应该是一个线对象数组,所以我应该在整个东西周围放置方括号。我认为应该在条目之间放置逗号。但是,当我这样做时,它仍然无效。我可以通过在索引行和类型行之间加一个逗号来使其有效,但这在直观上没有意义。
我如何修改上面的内容,以便我可以在 api 中使用格式良好的 JSON。
感谢您的任何建议。
解决方案
您当前格式的数据可以称为Interleaved,即有多种不同类型的记录,但它们之间的唯一关系是它们在文件中的位置。这种结构为用 JSON 表示提供了一个有趣的挑战,JSON 是一种对象表示法,也称为分层数据图。
在将此数据转换为 JSON 时,我们应该考虑结构将为最终消费者增加什么价值,使数据更易于解析和消费总是有一些价值的,即使您不出售数据馈送,如果您可以降低成本,你以后需要回答的关于数据的问题就更少了。
集合中的两种记录类型是:
- 指数
- 文本输入
由于这些记录之间存在 1:1 的关系,因此在 JSON 输出中将这些记录之一嵌套在另一个记录中没有任何价值。两条记录之间也没有共享/公共字段,两者之间也没有链接字段。这意味着每个记录都依赖于另一个记录。
从消费者的角度来看,索引本身是没有意义的,索引通常是为了方便快速搜索或引用记录而设计的。
由于这里的任务是逐行处理数据,并且我们发现生成嵌套结构没有什么价值并且没有公共字段,因此可以轻松地将这个交错的数据集合并或展平为单个记录的简单数组
在分析数据之后,我们可能能够确定将其规范化为对象图的方法,但这需要重新处理整个文件,并且对消费用户的整体利益是有问题的,数据通常更容易被更广泛的数组消费如果它是扁平的,而不是嵌套结构,则工具的数量。
为了展平这些数据,我们从索引记录中获取字段,并将它们注入到文本条目中,在这个示例中,我还展平了本身是单个嵌套对象的索引结构:
[
{"index":"tolstoy","_id":27, "type":"line","line_id":100,"book":"War and Peace","speech_number":1,"speaker":"Sonya","text_entry":"Weep. It will do you good"},
{"index":"tolstoy","_id":28, "type":"line","line_id":101,"book":"War and Peace","speech_number":1,"speaker":"Sonya","text_entry":"I will call Pyotr."}
]
实现这一目标的步骤:
在文件前面加上一个开始数组的新行:
[
通过简单的查找和替换,在全局范围内删除
{"_index":
这是安全的通过替换以下内容加入索引和文本条目记录,包括用逗号换行:
}} {
如果您使用的是 Visual Studio,这可以通过简单的查找并使用正则表达式替换来实现,以下只是一个示例来说明将要替换的内容:
- 应用前面的转换后
现在用数组关闭字符附加整个文件:
]
}
用逗号附加每一行的结尾
4. 和 5. 可以颠倒,从自动化的角度来看,我发现作为一种更简单的方法来确保最后一行没有逗号
要考虑的事情:
扁平化索引后,我还建议在阅读这篇文章后将其名称更改为_id
我index_id
很惊讶我第一次错过了它。
总体而言,此文件中用于字段的名称很直观,但如果文件本身很大(如果这是一个问题......),那么您可以通过减少其他字段的名称来节省几个text_entry
字节,text
例如// , _speech_number
speechId
speechNo
speechNum
在减少数据集成的名称时,您应该尽量避免将列减少为模棱两可的术语,例如
line_id
tolid
或speech_number
to,sid
因为这会给消费者带来更多假设,这意味着您需要花费更多时间来记录或回答问题。
在优化数据馈送时,您需要在理论上可实现的目标与您和消费者可用资源的实际目标之间找到平衡。
- 由于不同的原因,每种情况都会有所不同。
如果文件中的每条记录都具有相同的字段值,则可以完全删除该字段,在当前示例type
中可能属于此类。
如果网络中的字节是一个问题,并且您想坚持使用 JSON,那么将数据规范化为嵌套对象图是一种选择,您应该使用某种映射或翻译服务来执行此操作,或者代码,我不会不要手动尝试,但它可能看起来像这样的嵌套数组:
- 索引(作者)
- 图书
- 演讲
- 文本条目
- 演讲
- 图书
如果您要将其处理成标准化结构,它可能看起来像这样:
对于一个大文件(已删除空格)可能会产生显着差异,同时仍然很容易通过表达式语法定位图中的节点,重要的是没有丢失任何信息。
推荐阅读
- cookies - 无法获取 cookie。稍后尝试 cookie 生成
- python-3.x - 根据条件更新时与 DataFrame 不兼容的索引器
- npm - NPM 是否尝试多次或仅安装一次相同的依赖包?
- css - 带有弹性容器的 vue-select
- flutter - Flutter overly_support showOverlayNotification:多个通知窗口相互堆叠
- mysql - 如何在mysql中选择匹配“多行条件”的行
- awk - How to insert word count as a string in a file?
- java - 对二维整数数组进行排序 Java
- javascript - 如何在文本中显示多行数字的汇总值 [SAPUI5]
- sql - 在sql分析中获取周数作为别名