【问题标题】:MongoDB: Using $sample with C# driverMongoDB:将 $sample 与 C# 驱动程序一起使用
【发布时间】:2018-01-13 19:40:47
【问题描述】:

我正在尝试使用 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() 的方法。

请帮忙。提前谢谢你。

【问题讨论】:

    标签: mongodb mongodb-.net-driver


    【解决方案1】:
    var sample = new BsonDocument 
    { 
        { 
            "$sample", new BsonDocument 
            { 
                {"size", 1000} 
            } 
        } 
    };
    
    var samples = _collection.Aggregate().AppendStage(new BsonDocumentPipelineStageDefinition<MyType, MyType>(sample));
    return await samples.ToListAsync();
    

    【讨论】:

      【解决方案2】:

      简单地说,

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

      别忘了加

      using MongoDB.Driver.Linq;
      

      【讨论】:

        【解决方案3】:

        我认为应该是的

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

        如果这不起作用,请告诉我。暂时不要启动windows系统来确认

        编辑(8 月 7 日):

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

        使用系统; 使用 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;
                }
            }
        }
        

        【讨论】:

        • 我也希望有类似的东西,但没有.Sample() 方法。
        • 让我检查系统并回复您
        • 这太棒了。谢谢!
        • 顺便说一句,您知道是否可以通过 C# 驱动程序运行原始查询?喜欢:await _collection.QueryAsync("db.media.aggregate({ $sample: { size: 1 }})"); 我没有看到这样的方法。
        • 我不确定。我查看了源代码,没有任何明显的地方可以让你这样做
        猜你喜欢
        • 2015-04-16
        • 2021-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-13
        • 1970-01-01
        • 2011-08-29
        相关资源
        最近更新 更多