2012-09-30 59 views
6

我有一個帶文件的mongo集合。每個文檔中有一個字段是0或1.我需要從數據庫中隨機抽取1000條記錄,並將該字段的文檔數量設爲1.我需要進行1000次抽樣。我該怎麼做 ?Mongo隨機採樣

+1

您能否接受答案? –

+0

[MongoDB的隨機記錄]可能的重複(http://stackoverflow.com/questions/2824157/random-record-from-mongodb) –

+0

嘿Aditya,你能接受一個答案嗎? – dalanmiller

回答

1

這裏是在mongo殼爲例..假設collname集合,並在thefield一個感興趣的值:

var total = db.collname.count(); 
var count = 0; 
var numSamples = 1000; 

for (i = 0; i < numSamples; i++) { 
    var random = Math.floor(Math.random()*total); 
    var doc = db.collname.find().skip(random).limit(1).next(); 
    if (doc.thefield) { 
     count += (doc.thefield == 1); 
    } 
} 
+0

這也回答了另一個問題:與SQL不同,MongoDB沒有真正的內置函數。此外,跳過可能(...可能)變得更大的隨機值麻煩,但取決於。 – Sammaye

1

我要編輯我的@Stennies評論回答這個但你也可以如果您要跳過大量的記錄(在這裏說得很大),請使用分隔符自動遞增ID索引作爲替代。

我寫了另一個回答另一個問題,很多像這樣的地方有一個人正在試圖找到集合的第n個記錄:

php mongodb find nth entry in collection

我的答案的後半部分基本上描述了一個潛在的方法,通過你可以解決這個問題。你仍然需要循環1000次才能得到隨機的排。

12

對於MongoDB 3.0和之前的版本,我使用SQL天的舊技巧(我認爲維基百科用於他們的隨機頁面功能)。我在每個需要隨機化的對象中存儲一個0到1之間的隨機數,我們稱之爲「r」。然後在「r」上添加一個索引。

db.coll.ensureIndex(r: 1); 

我們得到隨機X對象,你可以使用:

var startVal = Math.random(); 
db.coll.find({r: {$gt: startVal}}).sort({r: 1}).limit(x); 

這讓你在一個單一的查找查詢隨機對象。根據您的需要,這可能是矯枉過正的,但是如果您將要隨着時間的推移進行大量抽樣,這是一種非常有效的方式,不會在後端加載負載。

+0

太棒了!很聰明! –

+0

優雅的解決方案! –

-1

如果您使用的是mongoengine,則可以使用SequenceField生成增量計數器。

class User(db.DynamicDocument): 
    counter = db.SequenceField(collection_name="user.counters") 

然後獲取說100的隨機列表,請執行下列操作

def get_random_users(number_requested): 
    users_to_fetch = random.sample(range(1, User.objects.count() + 1), min(number_requested, User.objects.count())) 
    return User.objects(counter__in=users_to_fetch) 

,你會打電話

get_random_users(100)