2013-04-22 32 views
1

我需要使用Rails和MongoId來獲取一些隨機文檔。由於我計劃擁有非常大的集合,因此我決定在每個文檔中放置一個「隨機」字段,並使用該字段選擇文檔。我寫在模型下面的方法:mongoid範圍鏈上的執行方法

def random(qty) 
    if count <= qty 
    all 
    else 
    collection = [ ] 
    while collection.size < qty 
     collection << where(:random_field.gt => rand).first 
    end 
    collection 
    end 
end 

該功能的實際工作和收集充滿數量隨機元素。但是,當我嘗試使用它喜歡這樣一個範圍:

User.students.random(5) 

我得到:

undefined method `random' for #<Array:0x0000000bf78748> 

相反,如果我儘量讓像拉姆達範圍的方法獲得:

undefined method `to_criteria' for #<Array:0x0000000df824f8> 

鑑於我對在隨機之後應用任何其他示波器不感興趣,我如何在鏈中使用我的方法?

在此先感謝。

回答

0

我結束了使用下面的擴展Mongoid :: Criteria類。不知道這是不是最好的選擇。其實我相信這是相當慢,因爲它至少執行數量查詢。

我不知道not_in是否適用於正常的ActiveRecord模塊。但是,如果需要,您可以刪除not_in零件。這只是一個減少查詢次數的優化。

對於文檔數量比qty多(或更多)的集合,您應該準確地輸入數量查詢。

module Mongoid 
    class Criteria 

    def random(qty) 
     if count <= qty 
     all 
     else 
     res = [ ] 
     ids = [ ] 
     while res.size < qty 
      el = where(:random_field.gt => rand).not_in(id: ids).first 

      unless el.nil? 
      res << el 
      ids << el._id 
      end 
     end 
     res 
     end 
    end 

    end 
end 

希望對您有所幫助:)

+0

有趣的解決方案。在過去,我使用'pluck'來提取所有的id(相對較快),然後'sample(n)'來隨機抽取id。然後'Model.find(id)'拉出隨機n個模型。 – davogones 2013-04-27 06:06:48