解释 Rake 查询以创建 csv
Explain Rake query to create csv
我继承了一个连接到 mongo 数据库的 ruby 应用程序。不幸的是,我不知道 mongo 或 ruby,所以我在快速谷歌搜索和学习曲线上。
该应用程序存储地名及其经纬度、别名、人们的记忆和评论。它还计算一个地方被讨论了多少次。
下面的 rake 文件在 运行 时从 mongodb 中抓取所有位置并创建一个 csv,为每个位置吐出一行与用户、提到的次数、回忆等等等等
task :data_dump => :environment do
File.open("results.csv","w") do |file|
Location.all.each_with_index do |l,index|
puts "done #{index}"
file.puts [l.id, l.classification_count, l.position, l.created_at, l.classifications.collect{|c| c.text}, l.classifications.collect{|c| c.alternative_names }.flatten.join(";"), l.classifications.collect{|c| c.comment }.flatten.join(";"), l.memories.collect{|m| m.text}.flatten.join(";") ].join(",")
end
end
end
它工作得很好,生成了一个 CSV,然后我可以将其引入其他程序。问题是内容包含纯文本字段,它用换行符等破坏了 csv 的有效性,我想确保所有纯文本字段都正确包含在 CSV 中。
因此,如果我能更好地理解上述查询,我就可以输入正确的字段附件,以确保 csv 在加载到 GIS 软件时有效。
此外,在我的笔记本电脑上,上述内容大约需要 45 到 运行 一个小时,所以我想知道这是否是进行查询的最有效方法。
到目前为止,我们已经列出了大约 300000 个地名,而且这个数字会增加到几百万,所以只会变得更慢。
您可以使用 Ruby's 'csv' module:
生成 CSV
require 'csv'
task :data_dump => :environment do
CSV.open("results.csv","w") do |csv|
Location.all.each_with_index do |l,index|
puts "done #{index}"
csv << [l.id, l.classification_count, ...]
end
end
end
这将确保正确生成 CSV。至于速度,我只将 ActiveRecord 与关系数据库一起使用,但我想象问题是一样的 - The 1 + N Problem。基本上,它表示每次您使用 l.classifications.collect
或 l.memories.collect
时,它都需要执行查询以从数据库中获取所有 classifications/memories。解决方案是预先加载:
require 'csv'
task :data_dump => :environment do
CSV.open("results.csv","w") do |csv|
Location.all.includes(:classifications, :memories).each_with_index do |l,index|
puts "done #{index}"
csv << [l.id, l.classification_count, l.position, l.created_at, l.classifications.collect{|c| c.text}, l.classifications.collect{|c| c.alternative_names }.flatten.join(";"), l.classifications.collect{|c| c.comment }.flatten.join(";"), l.memories.collect{|m| m.text}.flatten.join(";") ]
end
end
end
(您可能需要为 alternative_names
这样做——我不记得嵌套预先加载的语法)。这将对数据库进行一次查询,这应该会快得多。
我继承了一个连接到 mongo 数据库的 ruby 应用程序。不幸的是,我不知道 mongo 或 ruby,所以我在快速谷歌搜索和学习曲线上。
该应用程序存储地名及其经纬度、别名、人们的记忆和评论。它还计算一个地方被讨论了多少次。
下面的 rake 文件在 运行 时从 mongodb 中抓取所有位置并创建一个 csv,为每个位置吐出一行与用户、提到的次数、回忆等等等等
task :data_dump => :environment do
File.open("results.csv","w") do |file|
Location.all.each_with_index do |l,index|
puts "done #{index}"
file.puts [l.id, l.classification_count, l.position, l.created_at, l.classifications.collect{|c| c.text}, l.classifications.collect{|c| c.alternative_names }.flatten.join(";"), l.classifications.collect{|c| c.comment }.flatten.join(";"), l.memories.collect{|m| m.text}.flatten.join(";") ].join(",")
end
end
end
它工作得很好,生成了一个 CSV,然后我可以将其引入其他程序。问题是内容包含纯文本字段,它用换行符等破坏了 csv 的有效性,我想确保所有纯文本字段都正确包含在 CSV 中。
因此,如果我能更好地理解上述查询,我就可以输入正确的字段附件,以确保 csv 在加载到 GIS 软件时有效。
此外,在我的笔记本电脑上,上述内容大约需要 45 到 运行 一个小时,所以我想知道这是否是进行查询的最有效方法。 到目前为止,我们已经列出了大约 300000 个地名,而且这个数字会增加到几百万,所以只会变得更慢。
您可以使用 Ruby's 'csv' module:
生成 CSVrequire 'csv'
task :data_dump => :environment do
CSV.open("results.csv","w") do |csv|
Location.all.each_with_index do |l,index|
puts "done #{index}"
csv << [l.id, l.classification_count, ...]
end
end
end
这将确保正确生成 CSV。至于速度,我只将 ActiveRecord 与关系数据库一起使用,但我想象问题是一样的 - The 1 + N Problem。基本上,它表示每次您使用 l.classifications.collect
或 l.memories.collect
时,它都需要执行查询以从数据库中获取所有 classifications/memories。解决方案是预先加载:
require 'csv'
task :data_dump => :environment do
CSV.open("results.csv","w") do |csv|
Location.all.includes(:classifications, :memories).each_with_index do |l,index|
puts "done #{index}"
csv << [l.id, l.classification_count, l.position, l.created_at, l.classifications.collect{|c| c.text}, l.classifications.collect{|c| c.alternative_names }.flatten.join(";"), l.classifications.collect{|c| c.comment }.flatten.join(";"), l.memories.collect{|m| m.text}.flatten.join(";") ]
end
end
end
(您可能需要为 alternative_names
这样做——我不记得嵌套预先加载的语法)。这将对数据库进行一次查询,这应该会快得多。