दिलचस्प पोस्ट
फेसबुक आईफोन ऐप द्वारा समर्थित सभी कस्टम यूआरएल योजनाएं क्या हैं? मैं ऑवैइडटाबलऑब्जेक्ट का उपयोग कैसे करूं? आईओसी कंटेनर्स का उपयोग; विशेष रूप से विंडसर डब्लूसीएफ सेवा में टाइमआउट वैल्यू को बढ़ाना जावास्क्रिप्ट में क्लास-आधारित ऑब्जेक्ट्स का कोई तरीका नहीं है? अनुरोधित संसाधन पर 'अभिगम-नियंत्रण-अनुमति-उत्पत्ति' शीर्षक मौजूद नहीं है। उत्पत्ति '…' इसलिए प्रवेश की अनुमति नहीं है मैं जावास्क्रिप्ट के साथ एक लिंक पर प्रोग्राममैटिक रूप से कैसे क्लिक करूं? ऐसी फाइल लोड नहीं कर सकता – रेलवे पर रूबी पर sqlite3 / sqlite3_native (लोड इरर) जावा सर्वलेट का उपयोग करके ब्राउज़र में पीडीएफ प्रदर्शित करें .NET ObservableDictionary फास्ट n बड़ी एन के लिए कश्मीर mod पी का चयन करें? सुरक्षाएक्सेप्शन: कॉलर यूआईडी XXXX प्रामाणिकेटर की यूआईडी से अलग है स्ट्रिंग में सफेद रिक्त स्थान को निकालने का सबसे तेज़ तरीका PHP: एक सरल निकालनाईमोजी फ़ंक्शन लिखना एक नल उदाहरण पर किसी सदस्य फ़ंक्शन को लागू करते समय क्या अपरिभाषित व्यवहार होता है?

रेल 3: रैंडम रिकॉर्ड प्राप्त करें

इसलिए, मैंने रेल 2 में एक यादृच्छिक रिकॉर्ड खोजने के लिए कई उदाहरण पाये हैं – पसंदीदा विधि ऐसा लगता है:

Thing.find :first, :offset => rand(Thing.count) 

एक नौसिखिया के कुछ होने के नाते मुझे यकीन नहीं है कि यह रेल 3 में नया खोज वाक्यविन्यास का उपयोग कैसे किया जा सकता है।

तो, बेतरतीब रिकॉर्ड खोजने के लिए "रेल 3 वे" क्या है?

वेब के समाधान से एकत्रित समाधान "रेल 3: रैंडम रिकॉर्ड प्राप्त करें"

 Thing.first(:order => "RANDOM()") # For MySQL :order => "RAND()", - thanx, @DanSingerman # Rails 3 Thing.order("RANDOM()").first 

या

 Thing.first(:offset => rand(Thing.count)) # Rails 3 Thing.offset(rand(Thing.count)).first 

दरअसल, रेल 3 में सभी उदाहरण काम करेंगे। लेकिन RANDOM का उपयोग बड़ी टेबल के लिए काफी धीमी है लेकिन अधिक एसक्यूएल-स्टाइल

युपीडी। आप निम्न अनुक्रमित अनुक्रमित स्तंभ (PostgreSQL वाक्यविन्यास) पर उपयोग कर सकते हैं:

 select * from my_table where id >= trunc( random() * (select max(id) from my_table) + 1 ) order by id limit 1; 

मैं एक परियोजना ( रेल 3.0.15, ruby ​​1.9.3-p125-perf ) पर काम कर रहा हूं जहां डीबी स्थानीयहोस्ट में है और उपयोगकर्ता तालिका में 100K रिकॉर्ड से थोड़ा अधिक है।

का उपयोग करते हुए

रैंड द्वारा क्रम ()

काफी धीमी है

User.order ( "रैंड (आईडी)")। पहले

हो जाता है

users चयन करें। * users द्वारा आदेश (आईडी) सीमा 1 से आदेश

जवाब देने के लिए 8 से 12 सेकंड लगते हैं !!

रेल लॉग:

उपयोगकर्ता लोड (11030.8 एमएमएस) का चयन करें users । * रैंड () के द्वारा users आदेश 1

mysql की व्याख्या से

 +----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------+ | 1 | SIMPLE | users | ALL | NULL | NULL | NULL | NULL | 110165 | Using temporary; Using filesort | +----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------+ 

आप देख सकते हैं कि कोई भी सूचकांक ( possible_keys = NULL ) उपयोग नहीं किया जाता है, एक अस्थायी तालिका बनाई जाती है और वांछित मूल्य प्राप्त करने के लिए एक अतिरिक्त पास की आवश्यकता होती है ( अतिरिक्त = अस्थायी का उपयोग करना; फाइलोर्ट का उपयोग करना )

दूसरी तरफ, दो हिस्सों में क्वेरी को विभाजित करके और रूबी का उपयोग करके, हमें प्रतिक्रिया समय में उचित सुधार होता है।

 users = User.scoped.select(:id);nil User.find( users.first( Random.rand( users.length )).last ) 

(; कंसोल उपयोग के लिए शून्य)

रेल लॉग:

यूजर लोड (25.2 एमएमएस) users लोड से लोड आईडी (0.2 एमएमएस) का चयन करें usersusers जहां users id = 106854 LIMIT 1

और mysql की समझाने का कारण बताता है:

 +----+-------------+-------+-------+---------------+--------------------------+---------+------+--------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+--------------------------+---------+------+--------+-------------+ | 1 | SIMPLE | users | index | NULL | index_users_on_user_type | 2 | NULL | 110165 | Using index | +----+-------------+-------+-------+---------------+--------------------------+---------+------+--------+-------------+ +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ | 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | | +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ 

अब हम केवल इंडेक्स और प्राथमिक कुंजी का उपयोग कर सकते हैं और नौकरी को लगभग 500 गुना तेज कर सकते हैं!

अद्यतन करें:

जैसा कि टिप्पणी में आईसीएन्टीबेकॉल द्वारा बताया गया है कि उपरोक्त समाधान में एक दोष है यदि तालिका में नष्ट किए गए रिकॉर्ड हैं।

उसमें एक वैकल्पिक हल हो सकता है

 users_count = User.count User.scoped.limit(1).offset(rand(users_count)).first 

जो दो प्रश्नों का अनुवाद करता है

 SELECT COUNT(*) FROM `users` SELECT `users`.* FROM `users` LIMIT 1 OFFSET 148794 

और लगभग 500ms में चलता है

मैंने ऐसा करने के लिए एक रेल 3 मणि बनाया जो बड़े तालिकाओं पर बेहतर प्रदर्शन करता है और आपको चेन रिलेशनशिप और स्कोप की अनुमति देता है:

https://github.com/spilliton/randumb

(संपादित करें): मेरे मणि का मूलभूत व्यवहार मूल रूप से अभी ऊपर के समान दृष्टिकोण का उपयोग करता है, लेकिन अगर आप चाहें तो पुराने तरीके का उपयोग करने का विकल्प है 🙂

यदि पोस्टग्रेज़ का उपयोग कर रहे हैं

 User.limit(5).order("RANDOM()") 

यदि MySQL का उपयोग करना

 User.limit(5).order("RAND()") 

दोनों उदाहरणों में आप उपयोगकर्ता तालिका से बेतरतीब ढंग से 5 रिकॉर्ड का चयन कर रहे हैं। यहां कंसोल में प्रदर्शित वास्तविक एसक्यूएल क्वेरी है।

 SELECT * FROM users ORDER BY RANDOM() LIMIT 5 

ये रहा

रेल मार्ग

 #in your initializer module ActiveRecord class Base def self.random if (c = count) != 0 find(:first, :offset =>rand(c)) end end end end 

प्रयोग

 Model.random #returns single random object 

या दूसरा विचार है

 module ActiveRecord class Base def self.random order("RAND()") end end end 

उपयोग:

 Model.random #returns shuffled collection 

वास्तव में जो पोस्ट किए गए उत्तरों में से अधिकांश बड़ी तालिकाओं (1 लाख मिलियन पंक्तियों) पर अच्छा प्रदर्शन नहीं करेंगे यादृच्छिक क्रम जल्दी कुछ सेकंड लेता है, और मेज पर एक गिनती भी काफी लंबा लेता है।

इस परिस्थिति में मेरे लिए अच्छी तरह से काम करने वाला समाधान RANDOM() का उपयोग जहां एक शर्त के साथ होता है:

 Thing.where('RANDOM() >= 0.9').take 

एक लाख से अधिक पंक्तियों के साथ तालिका में, यह क्वेरी आम तौर पर 2ms से कम लेता है

यह मेरे लिए बहुत उपयोगी था, लेकिन मुझे थोड़ी अधिक लचीलेपन की आवश्यकता है, इसलिए मैं यही करता हूं:

Case1: एक यादृच्छिक रिकॉर्ड स्रोत ढूँढना : ट्रेवर टर्क साइट
थिंग.आरबी मॉडल में इसे जोड़ें

 def self.random ids = connection.select_all("SELECT id FROM things") find(ids[rand(ids.length)]["id"].to_i) unless ids.blank? end 

तो अपने नियंत्रक में आप ऐसा कुछ कह सकते हैं

 @thing = Thing.random 

Case2: एकाधिक यादृच्छिक रिकॉर्ड (कोई दोहराव नहीं) स्रोत ढूँढना : याद नहीं कर सकते
मुझे 10 दोहरावों के साथ 10 यादृच्छिक रिकॉर्ड खोजने की आवश्यकता थी, इसलिए मुझे यह काम मिला
अपने नियंत्रक में:

 thing_ids = Thing.find( :all, :select => 'id' ).map( &:id ) @things = Thing.find( (1..10).map { thing_ids.delete_at( thing_ids.size * rand ) } ) 

यह 10 यादृच्छिक रिकॉर्ड पाएंगे, हालांकि यह उल्लेखनीय है कि यदि डाटाबेस विशेष रूप से बड़ा है (लाखों रिकॉर्ड), यह आदर्श नहीं होगा, और प्रदर्शन में बाधा पड़ेगी क्या कुछ हज़ारों रिकॉर्ड तक अच्छा प्रदर्शन होगा जो मेरे लिए पर्याप्त थे

एक सूची से बेतरतीब ढंग से एक आइटम चुनने के लिए रूबी विधि sample । ActiveRecord के लिए एक कुशल sample बनाने की इच्छा है, और पिछले उत्तरों के आधार पर, मैंने इसका उपयोग किया था:

 module ActiveRecord class Base def self.sample offset(rand(size)).first end end end 

मैं इसे lib/ext/sample.rb में डाल दिया और फिर इसे config/initializers/monkey_patches.rb :

 Dir[Rails.root.join('lib/ext/*.rb')].each { |file| require file } 

रेल 5 में काम करता है और डीबी अज्ञेयवादी है:

यह आपके नियंत्रक में है:

 @quotes = Quote.offset(rand(Quote.count - 3)).limit(3) 

आप कर सकते हैं, ज़ाहिर है, यह एक चिंता में डाल दिया जैसा कि यहां दिखाया गया है ।

एप्लिकेशन / मॉडल / चिंताओं / randomable.rb

 module Randomable extend ActiveSupport::Concern class_methods do def random(the_count = 1) records = offset(rand(count - the_count)).limit(the_count) the_count == 1 ? records.first : records end end end 

फिर…

एप्लिकेशन / मॉडल / book.rb

 class Book < ActiveRecord::Base include Randomable end 

इसके बाद आप बस ऐसा कर सकते हैं:

 Books.random 

या

 Books.random(3) 

आप ActiveRecord में नमूना () का उपयोग कर सकते हैं

उदाहरण के लिए

 def get_random_things_for_home_page find(:all).sample(5) end 

स्रोत: http://thinkingeek.com/2011/07/04/easily-select-random-records-rails/

अगर ओरेकल का उपयोग करना

 User.limit(10).order("DBMS_RANDOM.VALUE") 

उत्पादन

 SELECT * FROM users ORDER BY DBMS_RANDOM.VALUE WHERE ROWNUM <= 10 

तालिका से कई यादृच्छिक रिकॉर्ड प्राप्त करने का एक बहुत आसान तरीका। यह 2 सस्ते प्रश्नों को बनाता है

Model.where(id: Model.pluck(:id).sample(3))

आप "3" को यादृच्छिक रिकॉर्ड की संख्या में बदल सकते हैं।

मैं इस मुद्दे पर एक छोटा सा आवेदन विकसित कर रहा था, जहां मैं अपने डीबी से एक यादृच्छिक प्रश्न चुनना चाहता था। मैंनें इस्तेमाल किया:

 @question1 = Question.where(:lesson_id => params[:lesson_id]).shuffle[1] 

और यह मेरे लिए अच्छी तरह से काम कर रहा है मैं इस बात पर बात नहीं कर सकता कि बड़े DBs के प्रदर्शन के बाद से यह सिर्फ एक छोटा अनुप्रयोग है।