Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB: Using $sample with C# driver

I'm trying to express the following query using the MongoDB C# driver (2.4.4):

db.media.aggregate({ $sample: { size: 1 }})

This what I have so far:

BsonDocument sample = new BsonDocument
{
    { "$sample", new BsonDocument { { "size", 1 } } }
};
MongoBlob mongoBlob = await _collection
    .Aggregate()
    .Group<MongoBlob>(sample)
    .FirstOrDefaultAsync();

I cannot put the sample to .Aggregate(AggregateOptions options = null) and putting it into the .Group(...) is obviously wrong. There is also no any like a .Sample() method.

Please, help. Thank you in advance.

like image 648
Roman Klimenko Avatar asked Dec 24 '22 15:12

Roman Klimenko


2 Answers

Simply,

var randEl = await collection.AsQueryable().Sample(1).FirstOrDefaultAsync();

Do not forget add

using MongoDB.Driver.Linq;
like image 134
Андрей Пухкало Avatar answered Jan 05 '23 03:01

Андрей Пухкало


I believe it should be

MongoBlob mongoBlob = await _collection
    .Aggregate()
    .Sample(1)
    .FirstOrDefaultAsync();

If this doesn't work then let me know. Don't have windows system up right now to confirm

Edit (7-AUG):

Turns out its not that simple. The sample method doesn't exists in current driver. The classes which handle this are internal so no straight forward way to inherit. So worked out a solution based on reflection and a hack. Where you add a Stage to the pipeline and then edit it through reflection. Below is a working sample of my demo code

using System; using MongoDB.Bson; using MongoDB.Driver; using System.Reflection;

namespace TestMongo
{
    public static class MainClass
    {
        static IMongoClient _client;
        static IMongoDatabase _database;

        public static IAggregateFluent<BsonDocument> Sample(this IAggregateFluent<BsonDocument> agg, int count){
            var new_agg = agg.Skip(10);
            var stage =new_agg.Stages[new_agg.Stages.Count-1];
            var newDoc = new BsonDocument { 
                { "$sample", new BsonDocument {
                        {"size", count}
                    } } 
            };
            stage.GetType().GetField("_document"
             , BindingFlags.Instance | BindingFlags.NonPublic)
                 .SetValue(stage, newDoc);
            return new_agg;
        }

        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            _client = new MongoClient();
            _database = _client.GetDatabase("jobs");

            var col = _database.GetCollection<BsonDocument>("results");

            var agg = col.Aggregate().Sample(1);

            var data = agg.FirstOrDefault();
            data = null;
        }
    }
}
like image 21
Tarun Lalwani Avatar answered Jan 05 '23 03:01

Tarun Lalwani