我正在创建一个原始的SQL upsert,我有一个相当大的ActiveRecord关系数组,我需要转换为一个哈希。我需要键入哈希来选择我正在选择的其中一个参数,这样我就可以快速得到该值。
I found this response using as_json我几乎可以得到我需要的东西,但它并不完全存在。
profiles = Profile.all.select(:id, :foo) #returns an array of ActiveRecord Relations
profiles = profiles.as_json
产量
{:id => 123, :foo => "bar"}
{:id => 456, :foo => "baz"}
但我想要的是
{123 => "bar", 456 => "baz"}
我意识到我可以将as_json的结果映射到一个新的哈希,但我必须在几百万条记录上相当频繁地运行它。这也是一个较大的rake任务的一小部分,我希望将所有记录循环到最小。
我手动执行此操作而不是让ActiveRecord处理它的原因是它最初需要24小时才能运行任务,即使使用activerecord-import也只能加速约12小时。 I chose to go with using raw sql based off the benchmarks made in this blogpost
答案 0 :(得分:3)
在Rails4中,你可以做到
A,B
1.000000000000000000e+00,2.000000000000000000e+00
3.000000000000000000e+00,4.000000000000000000e+00
5.000000000000000000e+00,6.000000000000000000e+00
答案 1 :(得分:1)
你可以使用Profile.connection.select_all("select id, foo from profiles;")
=> [{"id" => xxx, "foo" => xxx}, {}, .....]
方法获取一个哈希数组而不是ActiveRecord对象,它更快,内存消耗更少。
public void queryBundleWithName(){
var query = ParseObject.GetQuery ("AssetBundle").
WhereEqualTo("name", "Board");
query.FirstAsync().ContinueWith(t =>{
ParseObject relatedObjects = t.Result;
string name = relatedObjects.Get<string>("name");
//isFinish = true;
urlVideo = relatedObjects.Get<ParseFile>("video").Url.AbsoluteUri;
textResult.text = urlVideo;
Screen.orientation = ScreenOrientation.LandscapeLeft;
Handheld.PlayFullScreenMovie (urlVideo, Color.black, FullScreenMovieControlMode.CancelOnInput, FullScreenMovieScalingMode.AspectFill);
});
}
然后将结果转换为您想要的格式。
答案 2 :(得分:0)
在profile
模型上,您可以执行此操作以获得所需结果:
def self.to_hash
Hash[*all.map{|p| [p.id, p.foo]}.flatten]
end
然后,您可以致电:Profile.select(:id, :foo).to_hash
答案 3 :(得分:0)
我可能会绕过ActiveRecord并将数据从数据库中直接插入Hash,如下所示:
Profile.connection
.execute('select id, foo from profiles')
.each_with_object({}) { |row, h| h[row['id'].to_i] = row['foo'] }
或者更好(IMO),也可以绕过Rails和Ruby,并使用SQL,临时表等在数据库中执行所有操作。当您处理大量数据时,最好的选择通常是完全忽略你的应用程序并在数据库中做所有事情;数据库非常适合处理大量数据,这是他们所做的事情。