2011-09-23 17 views
8

MapReduce aracılığıyla bir dizi kimlik aldım. Bu kimlikleri bazı ölçütlere göre sıralıyorum ve şimdi bu nesneleri şu sırayla almam gerekiyor:Moğol: iray dizisini bul

MyModel.find(ids) 

Doğru? Ancak, sipariş kimlikleri saklanmayan nesneler döndürür. Bu saklı kimlikleri olarak sadece aynı sırayla getirilen nesneler döndürmez sadece aynı

olarak
MyModel.where(:_id.in => ids) 

gibi görünüyor.

Şimdi iş yapacak bu

ids.map{|id| MyModel.find(id)} 

yapabilirsiniz ama veritabanını birçok defalarca yere vuracak.

cevap

9

Tüm nesnelere sahip olduktan sonra siparişi elle yapabilirsiniz. Böyle bir şey:

ordering = { } 
ids.each_with_index { |id, i| ordering[id] = i } 
objs = MyModel.find(ids).sort_by { |o| ordering[o.id] } 
+1

her öğeyi db'den daha hızlı mı alıyor? – fl00r

+0

@ fl00r: Modelleri almak için tek bir MongoDB erişimi ve istenen sırada bir şeyler almak için basit bir sıralama (Schwartzian Transform ile inşa edilmiş) olmalıdır. Veritabanı erişimi genellikle pahalı bir parçasıdır. Kıyaslamayı deneyin, gerçek verilere erişim olmadan hiçbir şeyi garanti etmek zordur. –

+0

@muistooshort, Benzer bir sorunla karşı karşıyayım. Genel olarak, db isabetleri en aza indirmek için daha iyi bir uygulama olacağını doğru mu? –

10

benzer bir sorun üzerinde çalışıyor ve biraz daha özlü bir çözüm bulunmuş muydu: temelde sadece öğenin dizinini dolanabilir sıralama bloğunu kullanarak

objs = MyModel.find(ids).sort_by{|m| ids.index(m.id) } 

.