Мне нужно отфильтровать некоторые данные из файла 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? любая помощь приветствуется.