2010-06-09 21 views
18

Tôi có một kho dữ liệu với khoảng 1.000.000 thực thể trong một mô hình. Tôi muốn lấy 10 thực thể ngẫu nhiên từ điều này.Tìm nạp một bản ghi ngẫu nhiên từ kho dữ liệu của Máy ứng dụng của Google?

Tôi không chắc chắn cách thực hiện việc này? ai đó có thể giúp được không?

+0

có thể trùng lặp của [Truy vấn cho N bản ghi ngẫu nhiên trên kho dữ liệu Appengine] (http://stackoverflow.com/questions/1105004/querying-for-n-random-records-on-appengine-datastore) –

Trả lời

21

Chỉ định từng thực thể một số ngẫu nhiên và lưu trữ nó trong thực thể. Sau đó truy vấn mười bản ghi có số ngẫu nhiên lớn hơn (hoặc nhỏ hơn) một số số ngẫu nhiên khác.

Điều này không hoàn toàn ngẫu nhiên, vì các thực thể có số ngẫu nhiên lân cận sẽ có xu hướng hiển thị cùng nhau. Nếu bạn muốn đánh bại điều này, hãy làm mười truy vấn dựa trên mười số ngẫu nhiên, nhưng điều này sẽ kém hiệu quả hơn.

+0

Chính xác. Có thể muốn đề cập đến phạm vi (0..1 là tiêu chuẩn) cho các số ngẫu nhiên. –

+4

Một khả năng để tăng tính ngẫu nhiên mà không làm tổn thương hiệu quả thời gian đọc sẽ là enqueue một nhiệm vụ để gán số ngẫu nhiên mới cho các thực thể bạn đã nạp, vì vậy nếu bạn nhấn một trong số họ một lần nữa bạn sẽ không nhận được cùng một hàng xóm với nó. – geoffspear

+0

@NickJohnson bạn có thể làm rõ về phạm vi tiêu chuẩn không? Xin lỗi, tôi không hiểu ý bạn là gì (0..1)? Ngoài ra, đối với cả hai: Tôi lo lắng về việc sử dụng bộ lọc bất bình đẳng cho hoạt động này (vì trong một số truy vấn tôi cần nó là ngẫu nhiên nhưng đồng thời chạy bộ lọc bình đẳng trên thuộc tính khác). Làm thế nào xấu là nó để làm 10 truy vấn, là nó về cơ bản 10x chi phí? – iceanfire

3

Câu trả lời của Jason Hall và the one here không phải là khủng khiếp, nhưng như ông đề cập, chúng cũng không thực sự ngẫu nhiên. Thậm chí làm mười truy vấn sẽ không được ngẫu nhiên nếu, ví dụ, các số ngẫu nhiên tất cả được nhóm lại với nhau. Để giữ cho mọi thứ thực sự ngẫu nhiên, đây là hai giải pháp khả thi:

Giải pháp 1

Gán một chỉ số cho từng đối tượng kho dữ liệu, theo dõi các chỉ số tối đa, và ngẫu nhiên chọn một chỉ số mỗi khi bạn muốn để có được một kỷ lục ngẫu nhiên:

MyObject.objects.filter('index =', random.randrange(0, maxindex+1))

Upside: Quả thật ngẫu nhiên. Nhanh.

Phía dưới: Bạn phải duy trì đúng các chỉ mục khi thêm và xóa đối tượng, điều này có thể làm cho cả hai thao tác hoạt động O (N).

Giải pháp 2

Gán một số ngẫu nhiên cho mỗi số kho dữ liệu khi nó được tạo ra. Sau đó, để có được một bản ghi ngẫu nhiên lần đầu tiên, truy vấn cho một bản ghi với số ngẫu nhiên lớn hơn một số số ngẫu nhiên và thứ tự khác theo các số ngẫu nhiên (ví dụ: MyObject.order('rand_num').filter('rand_num >=', random.random())). Sau đó lưu truy vấn đó dưới dạng con trỏ trong memcache. Để có được một bản ghi ngẫu nhiên sau lần đầu tiên, hãy tải con trỏ từ memcache và chuyển đến mục tiếp theo. Nếu không có mục nào sau lần đầu tiên, hãy chạy lại truy vấn.

Để ngăn chuỗi các đối tượng lặp lại, trên mỗi kho dữ liệu đọc, hãy cho thực thể bạn vừa đọc một số ngẫu nhiên mới và lưu nó trở lại kho dữ liệu.

Phía trên: Thật ngẫu nhiên. Không có chỉ số phức tạp nào để duy trì.

Phía dưới: Cần theo dõi con trỏ. Cần phải làm một đặt mỗi khi bạn nhận được một hồ sơ ngẫu nhiên.

+0

"Thậm chí làm mười truy vấn sẽ không được ngẫu nhiên nếu, ví dụ, các số ngẫu nhiên được nhóm lại với nhau" - Tôi đoán bạn đang nói về các số ngẫu nhiên được gán cho các hàng dữ liệu. Đây chỉ là vấn đề đối với số lượng bản ghi nhỏ - độ lệch chuẩn của khoảng trống giữa các giá trị co lại khi số lượng giá trị tăng lên, đến mức không đáng kể về mặt thống kê. Giải pháp của bạn 1 yêu cầu bộ đếm đơn điệu, đó là một hoạt động chậm và tốn kém trên App Engine. Giải pháp 2 sử dụng lựa chọn mà không cần thay thế, khác với những gì OP yêu cầu. –

+0

Phải, cách tiếp cận ngây thơ bị hỏng nếu không có nhiều bản ghi hoặc nếu bạn đang truy xuất chúng với tốc độ cao. Ngoài ra, khi giá trị rand_num được đặt, phân phối của chúng được cố định. Bạn sẽ không nhận được một bản phân phối đồng đều tốt và sẽ có một số hồ sơ nhất định sẽ hiếm khi được chọn. – speedplane

+0

Không, đó là quan điểm của tôi - số lượng bản ghi càng lớn, độ lệch chuẩn càng nhỏ. Nghĩa là, sẽ có ít thực thể ít hơn có khoảng thời gian nhỏ bất thường được gán cho chúng. Đề xuất của Wooble về việc chỉ định lại số khi bạn chọn một bản ghi cũng sẽ giúp chống lại điều này. –

Các vấn đề liên quan