2012-09-30 40 views
6

Tôi có một bộ sưu tập mongo với tài liệu. Có một trường trong mọi tài liệu là 0 HOẶC 1. Tôi cần lấy mẫu ngẫu nhiên 1000 bản ghi từ cơ sở dữ liệu và đếm số lượng tài liệu có trường đó là 1. Tôi cần thực hiện lấy mẫu này 1000 lần. Tôi phải làm nó như thế nào ?Lấy mẫu ngẫu nhiên từ Mongo

+1

Bạn có thể chấp nhận câu trả lời không? –

+0

có thể trùng lặp của [Bản ghi ngẫu nhiên từ MongoDB] (http://stackoverflow.com/questions/2824157/random-record-from-mongodb) –

+0

Xin chào Aditya, bạn có thể chấp nhận câu trả lời không? – dalanmiller

Trả lời

1

Dưới đây là một ví dụ trong vỏ mongo .. giả một bộ sưu tập của collname, và một giá trị quan tâm trong 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

Điều này cũng trả lời một câu hỏi khác: không giống như SQL, MongoDB không có chức năng dựng sẵn cho điều này thực sự.Ngoài ra, bỏ qua có thể (... có thể) trở nên rắc rối cho các giá trị ngẫu nhiên lớn hơn, mặc dù phụ thuộc. – Sammaye

1

tôi sẽ chỉnh sửa nhận xét của tôi về @Stennies trả lời với điều này, nhưng bạn cũng có thể sử dụng một chỉ số ID tăng tự động seprate ở đây như là một thay thế nếu bạn đã bỏ qua số lượng HUGE của hồ sơ (nói chuyện rất lớn ở đây).

tôi đã viết câu trả lời khác cho câu hỏi khác rất nhiều như thế này, nơi một số một đã cố gắng để tìm kỷ lục thứ n của bộ sưu tập:

php mongodb find nth entry in collection

Phần thứ hai của câu trả lời của tôi về cơ bản mô tả một phương pháp tiềm năng bằng cách mà bạn có thể tiếp cận vấn đề này. Bạn sẽ vẫn cần phải lặp 1000 lần để có được hàng ngẫu nhiên của khóa học.

12

Đối với MongoDB 3.0 và trước đó, tôi sử dụng một mẹo cũ từ các ngày SQL (mà tôi nghĩ Wikipedia sử dụng cho tính năng trang ngẫu nhiên của chúng). Tôi lưu trữ một số ngẫu nhiên giữa 0 và 1 trong mỗi đối tượng tôi cần phải ngẫu nhiên, hãy gọi trường đó là "r". Sau đó bạn thêm chỉ mục vào "r".

db.coll.ensureIndex(r: 1); 

Bây giờ để có được đối tượng x ngẫu nhiên, bạn sử dụng:

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

này mang đến cho bạn đối tượng ngẫu nhiên trong một truy vấn tìm duy nhất. Tùy thuộc vào nhu cầu của bạn, điều này có thể là quá mức cần thiết, nhưng nếu bạn định làm nhiều mẫu theo thời gian, đây là một cách rất hiệu quả mà không cần tải phụ trợ của bạn.

+0

Tuyệt vời! Rất thông minh! –

+0

giải pháp thanh lịch! –

-1

Nếu bạn đang sử dụng mongoengine, bạn có thể sử dụng một SequenceField để tạo ra một bộ đếm gia tăng.

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

Sau đó, để lấy một danh sách ngẫu nhiên nói 100, làm như sau

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) 

nơi bạn sẽ gọi

get_random_users(100) 
Các vấn đề liên quan