フラットファイルには 160 万件のレコードがあります。各レコードには、100 文字未満の短い文字列が 3 つまたは 4 つ含まれています。
これらのレコードは 800K しか必要ありません。これらのレコードを Mongo コレクションに書き込みます。他の 800K は無視されます。
ファイルの処理には約 15 分かかります。つまり、1 秒あたり約 1.67K レコードを処理します。これは予想されるパフォーマンスですか、それともプロセスをもっと高速にする必要がありますか (例: 5K レコード/秒、10K レコード/秒)?
以下のコード (@skip は、約 80 万個のアプリ ID のハッシュです)。
def updateApplicationDeviceTypes(dir, limit)
puts "Updating Application Data (Pass 3 - Device Types)..."
file = File.join(dir, '/application_device_type')
cols = getColumns(file)
device_type_id_col = cols[:device_type_id]
update = Proc.new do |id, group|
@applications_coll.update(
{ "itunes_id" => id },
{ :$set => { "devices" => group } }
# If all records for one id aren't adjacent, you'll need this instead
#{ :$addToSet => { "devices" => { :$each => group } } }
) unless !id or @skip[id.intern]
end
getValue = Proc.new { |r| r[device_type_id_col] }
batchRecords(file, cols[:application_id], update, getValue, limit)
end
# result to an array, before calling "update" on the array/id
def batchRecords(filename, idCol, update, getValue, limit=nil)
current_id = nil
current_group = []
eachRecord(filename, limit) do |r|
id = r[idCol]
value = getValue.call(r)
if id == current_id and !value.nil?
current_group << value
else
update.call(current_id, current_group) unless current_id.nil?
current_id = id
current_group = value.nil? ? [] : [value]
end
end
# Since the above is only called once for each row, we still
# have one group to update.
update.call(current_id, current_group)
end