Mongoid random document

前端 未结 9 1389
迷失自我
迷失自我 2021-02-06 00:49

Lets say I have a Collection of users. Is there a way of using mongoid to find n random users in the collection where it does not return the same user twice? For now lets say

9条回答
  •  伪装坚强ぢ
    2021-02-06 01:18

    The approach from @moox is really interesting but I doubt that monkeypatching the whole Mongoid is a good idea here. So my approach is just to write a concern Randomizable that can included in each model you use this feature. This goes to app/models/concerns/randomizeable.rb:

    module Randomizable
      extend ActiveSupport::Concern
    
      module ClassMethods
        def random(n = 1)
          indexes = (0..count - 1).sort_by { rand }.slice(0, n).collect!
    
          return skip(indexes.first).first if n == 1
          indexes.map { |index| skip(index).first }
        end
      end
    end
    

    Then your User model would look like this:

    class User
      include Mongoid::Document
      include Randomizable
    
      field :name
    end
    

    And the tests....

    require 'spec_helper'
    
    class RandomizableCollection
      include Mongoid::Document
      include Randomizable
    
      field :name
    end
    
    describe RandomizableCollection do
      before do
        RandomizableCollection.create name: 'Hans Bratwurst'
        RandomizableCollection.create name: 'Werner Salami'
        RandomizableCollection.create name: 'Susi Wienerli'
      end
    
      it 'returns a random document' do
        srand(2)
    
        expect(RandomizableCollection.random(1).name).to eq 'Werner Salami'
      end
    
      it 'returns an array of random documents' do
        srand(1)
    
        expect(RandomizableCollection.random(2).map &:name).to eq ['Susi Wienerli', 'Hans Bratwurst']
      end
    end
    

提交回复
热议问题