【问题标题】:search specific object from large json file in node js从节点 js 中的大型 json 文件中搜索特定对象
【发布时间】:2021-10-23 12:34:08
【问题描述】:

json文件结构如下:

{
    "products": [
    {
        "id": 6672129786814,
        "title": "rhPQbUW2fK5bhVCFuNFPsBGdolZYYcJ9gp4D4gskBHCOmGWb54",
        "variants":[{...},{...}],
        ....
    },{
        "id": 6672129786824,
        "title": "yuhPQbUW2fK5bhVCFfgdfgdfsglZYYcJ9gp4D4gskBHCOmGWb54",
        "variants":[{...},{...}],
        ....
    },{
        "id": 6672129786842,
        "title": "dfgUW2fK5bhVCFuNfgdsfgolZYYcJ9gp4D4gskBHCOmGWb54",
        "variants":[{...},{...}],
        ....
    },{
        "id": 6672129786935,
        "title": "aayuy44fK5bhVCFuNFPsBGdolZYYcJ9gp4D4gskBHCOmGWb54",
        "variants":[{...},{...}],
        ....
    }]
}

在这个 json 文件中可以有 500000 个对象。我需要在 product_id 上搜索产品基础。 我知道我们可以使用流式传输来读取文件,而且它也可以正常工作。它给了我作为 json 文件的所有对象的结果。但是现在我需要在 product_id 上搜索特定的产品基础。 在这里,我知道在获取所有产品期间,我可以使用循环迭代并搜索特定产品。但我不认为这是一种有效的搜索方式。

我正在寻找在读取文件期间根据 id 的值搜索特定对象的解决方案,以便我可以快速搜索并获取该特定对象,而不是一次获取所有对象然后迭代和然后匹配 id 并获取该对象。

var data = ''
var reader_stream = fs.createReadStream(file_path) //Create a readable stream
reader_stream.setEncoding('UTF8')

reader_stream.on('data', function(chunk) {
  data += chunk
})

reader_stream.on('end',function() {
  const products = JSON.parse(data)
  resolve(products)
})

reader_stream.on('error', function(err) {
  console.log(err.stack)
  reject(err.stack)
})

如果我使用块,它不确定它是否考虑对象的完整对象[因为它是块]。那么我应该如何逐个对象读取数据对象? 任何人都可以提供我可以快速获取特定对象的解决方案吗?

【问题讨论】:

  • 你可以检查你当前的块是否有右花括号。
  • 上面显示的示例对象只是示例,它包含子对象,因此在这种情况下关闭大括号将不起作用
  • 您是否从某种数据库中获取 500000 个产品?
  • 这只是一个关于从文件中获取/搜索大数据的模拟测试。所以那里没有使用数据库

标签: javascript node.js json object fs


【解决方案1】:

如果您可以信任具有示例中所示结构的文件({ first line with id, rest of lines, }),那么您可以使用https://stackoverflow.com/a/32599033/2729605 逐行读取,并在循环(可能是正则表达式?)然后您可以继续阅读行,直到找到另一个 id 或文件末尾,并在构建最终对象之前丢弃这些额外的行。改编自那里:

const regexStart = /"id" *: +6672129786842/
const regexStop = /"id"/

const fs = require('fs');
const readline = require('readline');

async function processLineByLine() {
  const fileStream = fs.createReadStream('input.txt');

  const rl = readline.createInterface({
    input: fileStream,
    crlfDelay: Infinity
  });
  // Note: we use the crlfDelay option to recognize all instances of CR LF
  // ('\r\n') in input.txt as a single line break.

  for await (const line of rl) {
    // Each line in input.txt will be successively available here as `line`.
    if ( regexStart.test(line) ) {
    // start storing subsequent lines
      for await (const line of rl) {
         if ( regexStop.test(line) ) {
         // produce final output and break
         }
      }
    }
  }
}

processLineByLine();

如果您的结构更加可变,这仍然是可行的,但是您需要将在查找 id 之前读取的行存储在某处,如果它们不是所需对象的一部分,则将其丢弃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多