さまざまなストアの製品情報を含む大きな (32 Mb) XML ファイルがたくさんあります。Heroku でホストされている Rails を使用しています。
これらの XML フィードを解析し、これらの製品をデータベースに書き込みたいと考えています。私は半作業ソリューションを持っていますが、非常に遅く、メモリを大量に消費します。
私はこれまで多かれ少なかれこれを使用してきました:
open_uri_fetched = open(xml_from_url)
xml_list = Nokogiri::HTML(open_uri_fetched)
xml_list.xpath("//product").each do |product|
// parsed nodes
// Model.create()
end
これはある程度機能しています。ただし、これにより Heroku でメモリの問題が発生し、スクリプトがクラッシュします。また、非常に遅いです (200 以上のフィードでこれを行います)。
Heroku は、私が今やろうとしている Nokogiri::XML::Reader を使用して問題を解決するように私に言いました。
私も使用して調べました:
ActiveRecord::Base.transaction do
Model.create()
end
Model.create() プロセスを高速化します。
1. 私の最初の質問: これは私の問題を解決するための正しい方法 (または少なくともまともな方法) ですか?
今、これは私がやろうとしていることです:
reader = Nokogiri::XML::Reader(File.open('this_feed.xml'))
reader.each do |node|
if node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT
if node.name.downcase == xname
puts "Name: " + node.inner_xml
use_name = node.inner_xml
end
end
end
質問 2: しかし、モデルの作成コードはどこに置くのですか?
ActiveRecord::Base.transaction do
Model.create(:name => use_name)
end
ループに入れると、ノードごとに作成しようとしますが、これは間違っています。xml-list 内の各製品の後に呼び出されるようにしたいですよね?
XML の読み取り中に構築されるハッシュを作成すると (そしてモデル作成の作成に使用されます)、最初に XML ファイルを開くのと同じくらいメモリを集中的に使用しませんか?
XML ファイルは、要するに次のようになります。
<?xml version="1.0" encoding="UTF-8" ?>
<products>
<product>
<name>This cool product</name>
<categories>
<category>Food</category>
<category>Drinks</category>
</categories>
<SKU />
<EAN />
<description>A long description...</description>
<model />
<brand />
<gender />
<price>126.00</price>
<regularPrice>126.00</regularPrice>
<shippingPrice />
<currency>SEK</currency>
<productUrl>http://www.domain.com/1.html</productUrl>
<graphicUrl>http://www.domain.com/1.jpg</graphicUrl>
<inStock />
<inStockQty />
<deliveryTime />
</product>
</products>