Как использовать yajl-ruby для анализа и фильтрации данных из большого файла JSON (размер 2G) - PullRequest
0 голосов
/ 14 апреля 2019

Мне нужно отфильтровать некоторые данные из файла 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"
    }
  ]
}

Проведя несколько исследований о разборе огромного json в ruby, я нашел https://github.com/dgraham/json-stream и https://github.com/brianmario/yajl-ruby, Я пытался json_stream, который занимает около 20 минут, и этот сайт https://github.com/dgraham/yajl-ffi#performance говорит, что

yajl-ruby быстрее

С json_stream я мог бы использовать некоторые call_backs, такие как start_object / end_object / key / value, чтобы узнать, когда объект анализируется, а затем выполнить некоторую обработку с этим объектом и продолжить.

Но с yajl-ruby я нахожу только call_back с именем "on_parse_complete". Его документ (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 {"имя": "Фред", «Команда»: «футбол», «Хобби»: «восхождение» } сделать что-нибудь по этому объекту

тогда объект { "Имя": "Тони", «Команда»: «баскетбол», «Хобби»: «рыбалка»} сделать что-нибудь по этому объекту

тогда объект { "Имя": "Алекс", «Команда»: «футбол», «хобби»: «кино» } сделать что-нибудь по этому объекту .....

Может быть, у меня есть некоторое недопонимание по поводу этого предложения

"Он передаст единственный параметр, объект ruby, созданный из последнего проанализированного объекта JSON" #

об обратном вызове

"on_parse_complete"

описано в документе, указанном выше.

Кто-нибудь знает, как это сделать с yajl-ruby? любая помощь приветствуется.

...