How to find 'N' random records from collection

744 views
Skip to first unread message

Mit Mehta

unread,
Jul 29, 2015, 7:35:00 AM7/29/15
to mongodb-user
Hi,

I want to retrieve 'N' (lets say 15 records) random records from particular collection. How can I get this? Please help me. Its very urgent.

Rhys Campbell

unread,
Jul 29, 2015, 9:10:53 AM7/29/15
to mongodb-user, mitme...@gmail.com
I don't know of anything similar ala SQL...

SELECT id
FROM myTable
ORDER BY RAND()
LIMIT 15;

Here's as close as I can think of...


use local
var n = db.oplog.rs.count();
var s = Math.floor(Math.random() * n);
db.oplog.rs.find().skip(s).limit(15);


There's number of things wrong with this... Start is random but next 15 records are returned in natural order. It's also possible to get less than 15 depending on skip point. Other than making 15 separate calls I'm not sure there's anything better.

Stephen Steneker

unread,
Jul 30, 2015, 9:53:11 PM7/30/15
to mongodb-user, mitme...@gmail.com
On Wednesday, 29 July 2015 21:35:00 UTC+10, Mit Mehta wrote:
I want to retrieve 'N' (lets say 15 records) random records from particular collection. How can I get this? Please help me. Its very urgent.

Hi Mit,

There currently (as at MongoDB 3.0) is no server-side feature to choose random documents. However, there is work in progress to add a $sample aggregation operator in the unstable/development branch of MongoDB 3.1. See https://jira.mongodb.org/browse/SERVER-533 and related issues.

In the interim, there are some other approaches to consider depending on your requirements:

 - choose a random skip() value based on the count of documents in a collection (not overly efficient, particularly for large skip values)

 - add random values to documents that can be indexed and used for selection (more efficient for large collections, but possible caveats on distribution bias): https://github.com/mongodb/cookbook/blob/master/content/patterns/random-attribute.txt


Regards,
Stephen

Stephen Steneker

unread,
Jul 30, 2015, 10:05:31 PM7/30/15
to mongodb-user, rhys.jame...@gmail.com
On Wednesday, 29 July 2015 23:10:53 UTC+10, Rhys Campbell wrote:
Here's as close as I can think of...


use local
var n = db.oplog.rs.count();
var s = Math.floor(Math.random() * n);
db.oplog.rs.find().skip(s).limit(15);

There's number of things wrong with this... Start is random but next 15 records are returned in natural order. It's also possible to get less than 15 depending on skip point. Other than making 15 separate calls I'm not sure there's anything better.

Hi Rhys,

You definitely would not want to use the oplog to find random documents from a given collection. The oplog is a special capped collection designed for used by replication.

There are a number of reasons why the oplog wouldn't be a suitable approach for random selection, including:
 - the oplog is a fixed size and over time only includes recent data changes (to the limit of the oplog size)
 - oplog documents would have to be parsed in order to find the original document
 - each update to a document creates a new oplog entry (so this would strongly bias recent documents with many updates)
 - the oplog has no indexes (and does not support adding any)

Regards,
Stephen

Mit Mehta

unread,
Jul 31, 2015, 12:17:30 AM7/31/15
to mongodb-user, mitme...@gmail.com, ste...@mongodb.com
Thanks a lot Stephen Steneker :)

Thanks & Regards,
Mit Mehta

Rhys Campbell

unread,
Jul 31, 2015, 2:44:53 AM7/31/15
to mongodb-user
Don't panic. It's just an example to illustrate the mechanics of the java script. I just happen to use the oplig as an example.

Rhys

Reply all
Reply to author
Forward
0 new messages