我需要使用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>
鉴于我对随机之后的任何其他范围不感兴趣,我如何在链中使用我的方法?
提前致谢。
答案 0 :(得分: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
希望您觉得这很有用:)