Expanding on the random concept, could create a random set of indexes
First, find the total resultset size:
var resultsCount = MongoCollection
.AsQueryable()
.Where(x => x.Type == 1)
.Count();
Then create the random indexes:
var sampleSize = 10;
var rnd = new Random();
var indexes = Enumerable.Range(0, resultsCount-1);
var randomSet = indexes
.OrderBy(r => rnd.NextDouble())
.Take(sampleSize)
.ToList();
Then apply to the query by zipping:
var result = MongoCollection
.AsQueryable()
.Where(x => x.Type == 1)
.Zip(indexes, (x, y)=> Tuple.Create(x,y))
.Where(tuple => randomSet.Any(r => r == tuple.Item2))
.Take(sampleSize) // for good measure, finish when all samples taken
.Select(t => t.Item1) // clear the indexes
.ToList();
It should be efficient memory-wise, but not so network-wise.
This is a test for Linqpad with simulated db items:
var resultsCount = 30;
var sampleSize = 10;
// Create a random set of indexes
var rnd = new Random();
var indexes = Enumerable.Range(0, resultsCount-1);
var randomSet = indexes.OrderBy(r => rnd.NextDouble()).Take(sampleSize).ToList();
randomSet.OrderBy(r => r).Dump("Random set of indexes");
// Simulated resultset
// for convenience simulate db items from index set
var db = indexes.Select(x => "Result" + x.ToString());
// The query
var sampleOfResults =
db.Zip(indexes, (x, y)=> Tuple.Create(x,y))
.Where(tuple => randomSet.Any(r => r == tuple.Item2))
.Take(sampleSize) // for good measure, finish when all samples taken
.Select(t => t.Item1); // clear the indexes
sampleOfResults.ToList().Dump("Sample");