使用MongoDB C#驱动程序2.4在查询中包含/排除字段

Jef*_*hao 6 mongodb-.net-driver

我们有一个包含服务器中文档的集合。每个文档就像:

{ _id: "...", Prop1: "", Prop2: "", Prop3: "", LargeField: "", ... }
Run Code Online (Sandbox Code Playgroud)

还有许多其他字段,但客户不需要。

我想将文档加载为MyDoc定义如下的类:

public class MyDoc {
    public string Id { get; set; }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }
    public string LargeField { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我试过了:

var client = new MongoClient(uri);
var database = client.GetDatabase("MyDatabase");
var collection = database.GetCollection<MyDocs>("MyDocs");
var allDocs = collection.Find().ToList();
Run Code Online (Sandbox Code Playgroud)

然后,它会加载所有的领域对每个文档,所以我必须把[BsonIgnoreExtraElements]MyDoc。这里的问题是文档很大,但是我只需要一个有限的字段子集。是否可以让驾驶员知道我只需要在类中定义的字段?

如果不是,是否可以排除某些字段(如)LargeField以缩小结果集?我试过了:

var fieldsBuilder = Builders<MyDoc>.Projection;
var fields = fieldsBuilder.Exclude(d => d.LargeField);
var allDocs = collection.Find().Project(fields).ToList();
Run Code Online (Sandbox Code Playgroud)

但是现在allDocs成为BsonDocument列表而不是MyDoc列表。如何查询MyDoc投影?

有人可以帮忙吗?在旧版MongoDB驱动程序中,这相当简单,但是我不知道如何在新驱动程序中做到这一点。谢谢。

小智 8

我有一个类似的问题,我相信您需要指定通用类型,由于某些原因,Project将自动采用BsonDocument。这应该将其从BsonDocument修复到您的类。

更改:

var allDocs = collection.Find().Project(fields).ToList();
Run Code Online (Sandbox Code Playgroud)

至:

var allDocs = collection.Find<MyDoc>().Project<MyDoc>(fields).ToList();
Run Code Online (Sandbox Code Playgroud)

至于如何仅包括某些字段,可以像使用builder(使用Include)或使用json形式的字符串一样来完成:

var allDocs = collection.Find<MyDoc>().Project<MyDoc>("{Prop1: 1, Prop2: 1}").ToList();
Run Code Online (Sandbox Code Playgroud)

我强烈建议您查看此人的职位上的投影:https : //www.codementor.io/pmbanugo/working-with-mongodb-in-net-part-3-skip-sort-limit-and-projections-oqfwncyka

从这篇文章:

这给我们带来了另一个差异:通过投影定义,它隐式地将文档类型从Student转换为BsonDocument,因此我们得到的是一个流畅的对象,其结果将是一个BsonDocument(即使我们正在使用的对象也是如此)。是学生类型)。如果我们想与学生一起工作,则必须指出我们仍然希望将类型保留为学生。


Gin*_*ano 5

较新的方式:

var fieldsBuilder = Builders<MyDoc>.Projection;
var fields = fieldsBuilder.Exclude(d => d.BigField1).Exclude(d => d.BigField2);

return Collection.Find(x => x.id.Equals(id)).Project<MyDoc>(fields).ToEnumerable();
Run Code Online (Sandbox Code Playgroud)

吉娜