如何使用yajl-ruby解析和过滤来自大json文件(2G大小)的数据

时间:2019-04-14 09:15:37

标签: ruby jsonparser yajl

我需要从json文件(大约2G大小)中过滤掉一些数据。 乔恩就像

{ "dataName": "staff",
  "version": 5,
  "data": [
    {"name":"Fred",
    "team":"football",
    "hobby":"climbing"
    },
     {"name":"Tony",
     "team":"basketball",
     "hobby":"fishing"},

    {"name":"alex",
      "team":"soccer",
      "hobby":"movies"
    }
  ]
}

在进行了一些关于在ruby中解析巨大的json的研究之后,我发现https://github.com/dgraham/json-streamhttps://github.com/brianmario/yajl-ruby,我尝试了大约20分钟的json_stream,这个网站https://github.com/dgraham/yajl-ffi#performance表示

yajl-ruby更快

借助json_stream,我可以使用诸如start_object / end_object / key / value之类的回调函数来了解何时解析对象,然后对该对象进行一些处理并继续。

但是使用yajl-ruby时,我只能找到一个名为“ on_parse_complete”的call_back。 其文档(https://www.rubydoc.info/github/brianmario/yajl-ruby/Yajl/Parser)表示

"#on_parse_complete= ⇒ Object
call-seq: on_parse_complete = Proc.new { |obj| … }

This callback setter allows you to pass a Proc/lambda or any other object that responds to #call.

#It will pass a single parameter, the ruby object built from the last parsed JSON object"#

然后我写一段类似的代码


require 'yajl'
def parse_farquaad f, chunk_size
   parser = Yajl::Parser.new

    parser.on_parse_complete = Proc.new do |obj|
      yield obj
    end

    f.each(chunk_size) { |chunk| parser << chunk }
  end

  File.open("big_file.json") do |f|
      parse_farquaad f, 8092 do |current_data_unit|
        puts "obj is:"
        puts current_data_unit
  end

我在小尺寸的示例json文件上进行测试(

请参阅开头给出的示例

,但是输出是#整个JSON obj#(一次全部转储),而不是 我想要的是逐个输出“数据”中的每个对象,就像我可以从表单json流中获取一样,在解析并输出“数据”中的每个obj之后,我可以像检查每个obj是否为数据一样对它进行处理我想要。

我的预期输出是:

首先,obj {“ name”:“ Fred”,    “ team”:“足球”,    “爱好”:“攀爬” } 在这个对象上做某事

然后obj  {“ name”:“ Tony”,    “ team”:“篮球”,    “爱好”:“钓鱼”} 在这个对象上做某事

然后obj  {“ name”:“ alex”,    “ team”:“足球”,     “爱好”:“电影”   } 在这个对象上做某事 .....

也许我对这句话有些误解

“它将传递一个参数,即从最后一个解析的JSON对象构建的ruby对象”#

关于回调

“ on_parse_complete”

如上所示文档中所述。

有人知道如何用yajl-ruby做到这一点吗?任何帮助表示赞赏。

0 个答案:

没有答案