簡體   English   中英

以內存有效的方式從 json 過濾壞 json 值

[英]filter bad json values from json in a memory efficient way

我們嘗試解析一些錯誤的 json。 不幸的是,它不是有效的 json,因為它在有效負載中返回未加引號的NaN

我們正在從長期棄用的request庫切換到axios 這似乎使我們當前修復此有效負載的方式的內存使用量增加了一倍,但我們的環境受到內存限制。 該文件為 19MB,我們的約束為 50MB。 我認為除了axios試圖做的解析之外,與正則表達式/解析有關的事情是在內存中制作另一個 json 副本。

我們在 axios 周圍使用了一個包裝器,因此直接與它交互是有限的。 我必須重新實現部分包裝器才能使用它,它是一個外部內部庫。

我知道我們要保留的密鑰,所以只丟棄結構的其余部分而不是處理 NaN 實際上是更可取的。

我們想要的結構,看起來像DataUsages[]

export interface DataUsages {
    dataUsageId: string;
    dataUsageName: string;
}

我們得到的結構在數組中的對象中有額外的項目,我們根本不關心"dataUsageDownstreamUsages" ,並且該鍵可以並且正在被丟棄`

[
  {
    "dataUsageId": "42",
    "dataUsageName": "myname",
    "dataUsageDownstreamUsages": [NaN]
  }
]

當前的

這是我們目前的方法

      const reg1 = /\[NaN]|NaN/gm
      const parsed: EDMDataUsages[] = JSON.parse(
        requireNonNullish(response.body, 'body').replace(reg1, '""').replace(/NAN/gm, ''),
      )   

流-json

現在我正在考慮為此使用stream-json

如果我使用解析器,它會保釋,大概是當它到達NaN時。 所以我正在查看disassembler程序,但我不明白如何使用它。

  const read = new Readable()
  read.push(requireNonNullish(response.body, 'body'))
  read.push(null)

  const pipeline = chain([read, disassembler(), pick({ filter: 'data' }), data => this.log.trace('data', data)])
  pipeline.on('data', data => this.log.trace('filter', data))

顯然這段代碼並不完整。

其他庫是可以接受的。 請提供一個完整的例子。

好的,首先讓我們創建一個假數據

function genreateFakeData() {
    const payload = { res: [] }
    const mock = {
        "dataUsageId": "42",
        "dataUsageName": "myname",
        "dataUsageDownstreamUsages": [NaN]
    }
    let totalFileSize = 0;
    const fileSize = 19;
    const SIZE_IN_BYTES = JSON.stringify(mock).length;
    const SIZE_IN_MB = SIZE_IN_BYTES / 1024 / 1024;

    while (totalFileSize < fileSize) {
        totalFileSize += SIZE_IN_MB;
        payload.res.push(mock);
    }
    fs.appendFileSync('fake.json', JSON.stringify(payload));
}

然后讓我們測試這是文件的正確大小

> ls -ltrh | grep fake
-rw-r--r--   1 naor.tedgi  staff    19M Jun 15 09:34 fake.json

讓我們在堆約束下運行節點應用程序並改變原始響應

node --max-old-space-size=50 index.js

index.js

const stream = require('stream');
const fs = require('fs');
const data = JSON.parse(fs.readFileSync('fake.json',{encoding:'utf8', flag:'r'}));
data.res.forEach(entry=>{
    delete entry.dataUsageDownstreamUsages
})
console.log(data)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM