MongoDB:在C#驱动程序中使用$ sample

时间:2017-08-06 10:20:35

标签: mongodb mongodb-.net-driver

我尝试使用MongoDB C#驱动程序表达以下查询(2.4.4):

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

这是我到目前为止所做的:

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

我无法将sample放到.Aggregate(AggregateOptions options = null)并将其放入.Group(...)显然是错误的。也没有像.Sample()方法那样。

请帮忙。提前谢谢。

3 个答案:

答案 0 :(得分:3)

我认为应该是

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

如果这不起作用,请告诉我。现在没有Windows系统确认

编辑(7-AUG):

事实证明并非如此简单。当前驱动程序中不存在示例方法。处理此问题的类是internal,因此没有直接的继承方式。因此,制定了基于反射和黑客的解决方案。将舞台添加到管道然后通过反射进行编辑的位置。以下是我的演示代码的工作示例

使用System;     使用MongoDB.Bson;     使用MongoDB.Driver;     使用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;
        }
    }
}

答案 1 :(得分:3)

简单地

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

别忘了添加

using MongoDB.Driver.Linq;

答案 2 :(得分:1)

var sample = new BsonDocument 
{ 
    { 
        "$sample", new BsonDocument 
        { 
            {"size", 1000} 
        } 
    } 
};

var samples = _collection.Aggregate().AppendStage(new BsonDocumentPipelineStageDefinition<MyType, MyType>(sample));
return await samples.ToListAsync();