1

我需要使用 Rails 和 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

这个函数确实有效,并且集合中充满了qty随机元素。但是当我尝试像这样的范围使用它时:

User.students.random(5)

我得到:

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

相反,如果我尝试使该方法类似于 lambda 范围,则会得到:

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

鉴于我对在随机范围之后应用任何其他范围不感兴趣,我如何在链中使用我的方法?

提前致谢。

4

1 回答 1

0

我最终使用以下扩展了 Mongoid::Criteria 类。不知道是不是最好的选择。实际上我相信它很慢,因为它至少执行qty查询。

我不知道not_in是否可用于普通的 ActiveRecord 模块。但是,如果需要,您可以删除not_in部分。这只是减少查询次数的优化。

在文档数量比 qty 多一倍(或更多)的集合上,您应该有准确的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

希望你觉得这个有用 :)

于 2013-04-22T17:45:33.537 回答